【问题标题】:Why is the output of fixed width unsigned integer negative while unsigned integer output wraps around as expected?为什么固定宽度无符号整数的输出为负,而无符号整数输出按预期环绕?
【发布时间】:2020-04-06 09:02:58
【问题描述】:
#include <iostream>

#define TRY_INT

void testRun() 
{
    #ifdef TRY_INT          //test with unsigned
    unsigned int value1{1}; //define some unsigned variables
    unsigned int value2{1};
    unsigned int value3{2};
    #else                   //test with fixed width
    uint16_t value1{1};     //define fixed width unsigned variables
    uint16_t value2{1};
    uint16_t value3{2};

    #endif

    if ( value1 > value2 - value3 )
    {
        std::cout << value1 << " is bigger than: " << value2 - value3 << "\n";
    }
    else
    {
        std::cout << value1 << " is smaller than: " << value2 - value3 << "\n";
    }

}

int main()
{
    testRun();

    return 0;
}

我得到无符号整数:

1 is smaller than: 4294967295

固定宽度的无符号整数,输出为:

1 is smaller than: -1

我的期望是它也会环绕,这与 std::cout 有关系吗?

【问题讨论】:

  • -1 的位表示(2 补码)是什么?
  • @RichardCritten, 0xFFFFFFFF?

标签: c++ unsigned-integer


【解决方案1】:

我猜是整体推广造成的。引用表格cppreference:

...算术运算符不接受小于 int 的类型作为参数,并且在左值到右值转换后自动应用整数提升(如果适用)。

unsigned charchar8_t(C++20 起)或unsigned short如果可以保持其整个值范围,则可以转换为int...

因此,如果uint16_t 只是您实现中unsigned short 的别名,则value2 - value3 使用int 类型计算,结果也是int,这就是显示-1 的原因。

对于unsigned int,不应用提升,整个计算都在这种类型中进行。


最新在线C++草稿,见[conv.prom/1]

boolchar16_­tchar32_­twchar_­t 以外的整数类型的纯右值,其整数转换等级小于int 的等级可以转换为@987654340 类型的纯右值@if int 可以表示源类型的所有值;否则,可以将源纯右值转换为unsigned int 类型的纯右值。

【讨论】:

    【解决方案2】:

    unsigned int 等价于uint32_tunsigned short int 等价于uint16_t

    因此,如果您使用unsigned short int 而不是unsigned int,您将获得与uint16_t 相同的行为。

    为什么会得到 -1?

    如果int 可以保存unsigned short int 的所有可能值,则积分提升将尝试将unsigned short int 转换为int。另一方面,如果不是这种情况,将执行到unsigned int 的整体提升。

    因此,减法很可能在 int 类型中完成,而不是 uint16_t

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-16
      • 2015-08-04
      • 2022-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多