为什么固定宽度无符号整数的输出为负而无符号整数输出按预期回绕?
Why is the output of fixed width unsigned integer negative while unsigned integer output wraps around as expected?
#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
使用固定宽度的 unsigned int,输出为:
1 is smaller than: -1
我的预期是它也会环绕,这与 std::cout 有关系吗?
估计是积分提升造成的。引用形式 cppreference:
...arithmetic operators do not accept types smaller than int
as arguments, and integral promotions are automatically applied after lvalue-to-rvalue conversion, if applicable.
unsigned char
, char8_t
(since C++20) or unsigned short
can be converted to int
if it can hold its entire value range...
因此,如果 uint16_t
在您的实现中只是 unsigned short
的别名,则 value2 - value3
是使用 int
类型计算的,结果也是 int
,这就是显示 -1
的原因。
对于 unsigned int
,不应用任何提升,整个计算都以此类型执行。
在最新的在线C++ Draft中,参见[conv.prom/1]:
A prvalue of an integer type other than bool
, char16_t
, char32_t
, or wchar_t
whose integer conversion rank is less than the rank of int
can be converted to a prvalue of type int
if int
can represent all the values of the source type; otherwise, the source prvalue can be converted to a prvalue of type unsigned int
.
unsigned int
等同于uint32_t
,unsigned 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
.
#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
使用固定宽度的 unsigned int,输出为:
1 is smaller than: -1
我的预期是它也会环绕,这与 std::cout 有关系吗?
估计是积分提升造成的。引用形式 cppreference:
...arithmetic operators do not accept types smaller than
int
as arguments, and integral promotions are automatically applied after lvalue-to-rvalue conversion, if applicable.
unsigned char
,char8_t
(since C++20) orunsigned short
can be converted toint
if it can hold its entire value range...
因此,如果 uint16_t
在您的实现中只是 unsigned short
的别名,则 value2 - value3
是使用 int
类型计算的,结果也是 int
,这就是显示 -1
的原因。
对于 unsigned int
,不应用任何提升,整个计算都以此类型执行。
在最新的在线C++ Draft中,参见[conv.prom/1]:
A prvalue of an integer type other than
bool
,char16_t
,char32_t
, orwchar_t
whose integer conversion rank is less than the rank ofint
can be converted to a prvalue of typeint
ifint
can represent all the values of the source type; otherwise, the source prvalue can be converted to a prvalue of typeunsigned int
.
unsigned int
等同于uint32_t
,unsigned 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
.