【问题标题】:Why int plus uint returns uint?为什么int加uint返回uint?
【发布时间】:2012-04-20 07:33:59
【问题描述】:

int 加上 unsigned int 返回一个 unsigned int。应该这样吗?

考虑这段代码:

#include <boost/static_assert.hpp>
#include <boost/typeof/typeof.hpp>
#include <boost/type_traits/is_same.hpp>

class test
{
    static const int          si = 0;
    static const unsigned int ui = 0;

    typedef BOOST_TYPEOF(si + ui) type;
    BOOST_STATIC_ASSERT( ( boost::is_same<type, int>::value ) ); // fails
};


int main()
{
    return 0;
}

【问题讨论】:

标签: c++ int unsigned integer-arithmetic


【解决方案1】:

该行为可能源于指针类型(内存位置,例如std::size_t)背后的逻辑加上内存位置差异(std::ptrdiff_t)也是内存位置。

换句话说,std::size_t = std::size_t + std::ptrdiff_t

当此逻辑转换为底层类型时,这意味着 unsigned long = unsigned long + longunsigned = unsigned + int

@supercat 的“其他”解释也可能是正确的。

很明显,unsigned 整数不是设计出来的,也不应该被解释为数学上的正数,甚至在原则上也不应该。见https://www.youtube.com/watch?v=wvtFGa6XJDU

【讨论】:

    【解决方案2】:

    无符号整数类型主要表现为包装抽象代数环的成员,这些值等价于 mod 2^N;人们可能会认为 N 位无符号整数不是表示特定整数,而是在底部 N 位中具有特定值的所有整数的集合。例如,如果将后 4 位为...1001...0101 的两个二进制数相加,则结果将是...1110。如果将...1111...0001 相加,结果将是...0000;如果从...0000 中减去...0001,结果将是...1111。请注意,上溢或下溢的概念实际上并没有任何意义,因为操作数的高位值是未知的,而结果的高位值是不感兴趣的。另请注意,将其高位已知的有符号整数与高位为“不知道/不关心”的整数相加应该产生一个高位为“不知道/不关心”的数字(其中是无符号整数类型的主要表现)。

    无符号整数类型不能作为环绕代数环成员的唯一地方是当它们参与比较、用于数值除法(这意味着比较)或提升为其他类型时。如果将无符号整数类型转换为更大的类型的唯一方法是为此目的使用运算符或函数,则使用这样的运算符或函数可以清楚地表明它正在对高位进行假设(例如,将“某个数字其低位为...00010110”转换为“其低位为...00010110且其高位全为零的数字)。不幸的是,C 不这样做。将有符号值添加到相同大小的无符号值会产生大小相同的无符号值(这对于上面对无符号值的解释是有意义的),但是将更大的有符号整数添加到无符号类型将导致编译器默默地假设后者的所有高位都是零。这种行为尤其可能令人烦恼的是,根据编译器的提升规则,一些编译器可能认为两个表达式具有相同的大小,而另一些则可能将它们视为不同的大小。

    【讨论】:

    • 反对者:想发表评论吗?无符号整数类型通常用于有效地计算低位并忽略较大值的高位(例如,使用uint8_t 值来计算一堆字节的总和)。我的描述与正常的描述不符,但它与这种用法一致,并且代表了大多数依赖于无符号整数包装行为的程序员的意图;它也与编译器生成的代码一致,例如uint16_t x,y,z; ... x=y*z;,在计算 y*z 之后,需要忽略除低 16 位以外的所有结果。
    【解决方案3】:

    如果“应该”是指“我的编译器是否按照标准运行”:

    C++2003:第 5 条,第 9 段:

    许多期望算术或枚举类型操作数的二元运算符会导致转换和产生 结果类型以类似的方式。目的是产生一个公共类型,这也是结果的类型。 这种模式称为通常的算术转换,定义如下:

    • 废话
    • 否则,废话
    • 其他,等等,...
    • 否则,如果任一操作数是无符号的,则另一个应转换为无符号。

    如果“应该”是指“如果不这样,世界会变得更美好吗”:我没有能力回答这个问题。

    【讨论】:

    • 我确信 C++ 标准委员会的目标是让世界变得更美好,所以我所说的“应该是”实际上是指“如果不是这样,为什么世界不会变得更美好”。
    • @Vahagn - 那么(int)0x70000000 + (unsigned int)0x70000000 将产生一个正值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多