无符号整数不工作 C++
Unsigned int not working C++
以下是不同的 programs/scenarios 使用 unsigned int
和各自的输出。我不知道为什么其中一些没有按预期工作。
预期输出:2
程序 1:
int main()
{
int value = -2;
std::cout << (unsigned int)value;
return 0;
}
// OUTPUT: 4294967294
程序 2:
int main()
{
int value;
value = -2;
std::cout << (unsigned int)value;
return 0;
}
// OUTPUT: 4294967294
程序 3:
int main()
{
int value;
std::cin >> value; // 2
std::cout << (unsigned int)value;
return 0;
}
// OUTPUT: 2
有人可以解释为什么程序 1 和程序 2 不起作用吗?抱歉,我是编码新手。
您期望从 int
到 unsigned int
的转换在保持其大小的同时简单地更改负值的符号。但这不是它在 C 或 C++ 中的工作方式。当涉及溢出时,无符号整数遵循模运算,这意味着从负值(例如 -1 或 -2)分配或初始化会环绕到最大和第二大无符号值,依此类推。因此,例如,这两个是等价的:
unsigned int n = -1;
unsigned int m = -2;
和
unsigned int n = std::numeric_limits<unsigned int>::max();
unsigned int m = std::numeric_limits<unsigned int>::max() - 1;
另请注意,程序 1 和 2 之间没有实质性区别。这完全取决于用于初始化或分配给无符号整数的值的符号。
将值从有符号转换为无符号会改变值的单个位的解释方式。让我们看一个带有 8 位值的简单示例,例如 char
和 unsigned char
。
字符值的取值范围为 -128 到 127。包括 0 这些是 256 (2^8) 个值。通常第一位表示该值是负数还是正数。因此只有最后7位可以用来描述实际值。
无符号字符不能取任何负值,因为没有位可以确定该值应该是负数还是正数。因此其取值范围为 0 到 256。
设置所有位后 (1111 1111
),无符号字符的值为 256。但是,简单字符值会将第一个位视为负值的指示符。坚持 two's complement 这个值将为 -1。
这就是从 int
到 unsigned int
的转换没有达到您预期的效果的原因,但它确实做到了它应该做的。
编辑
如果您只想从负值切换到正值,请自己编写一个像这样的简单函数
uint32_t makeUnsigned(int32_t toCast)
{
if (toCast < 0)
toCast *= -1;
return static_cast<uint32_t>(toCast);
}
通过这种方式,您可以将传入的 int
转换为最大值为 2^32 - 1
的 unsigned int
以下是不同的 programs/scenarios 使用 unsigned int
和各自的输出。我不知道为什么其中一些没有按预期工作。
预期输出:2
程序 1:
int main()
{
int value = -2;
std::cout << (unsigned int)value;
return 0;
}
// OUTPUT: 4294967294
程序 2:
int main()
{
int value;
value = -2;
std::cout << (unsigned int)value;
return 0;
}
// OUTPUT: 4294967294
程序 3:
int main()
{
int value;
std::cin >> value; // 2
std::cout << (unsigned int)value;
return 0;
}
// OUTPUT: 2
有人可以解释为什么程序 1 和程序 2 不起作用吗?抱歉,我是编码新手。
您期望从 int
到 unsigned int
的转换在保持其大小的同时简单地更改负值的符号。但这不是它在 C 或 C++ 中的工作方式。当涉及溢出时,无符号整数遵循模运算,这意味着从负值(例如 -1 或 -2)分配或初始化会环绕到最大和第二大无符号值,依此类推。因此,例如,这两个是等价的:
unsigned int n = -1;
unsigned int m = -2;
和
unsigned int n = std::numeric_limits<unsigned int>::max();
unsigned int m = std::numeric_limits<unsigned int>::max() - 1;
另请注意,程序 1 和 2 之间没有实质性区别。这完全取决于用于初始化或分配给无符号整数的值的符号。
将值从有符号转换为无符号会改变值的单个位的解释方式。让我们看一个带有 8 位值的简单示例,例如 char
和 unsigned char
。
字符值的取值范围为 -128 到 127。包括 0 这些是 256 (2^8) 个值。通常第一位表示该值是负数还是正数。因此只有最后7位可以用来描述实际值。
无符号字符不能取任何负值,因为没有位可以确定该值应该是负数还是正数。因此其取值范围为 0 到 256。
设置所有位后 (1111 1111
),无符号字符的值为 256。但是,简单字符值会将第一个位视为负值的指示符。坚持 two's complement 这个值将为 -1。
这就是从 int
到 unsigned int
的转换没有达到您预期的效果的原因,但它确实做到了它应该做的。
编辑
如果您只想从负值切换到正值,请自己编写一个像这样的简单函数
uint32_t makeUnsigned(int32_t toCast)
{
if (toCast < 0)
toCast *= -1;
return static_cast<uint32_t>(toCast);
}
通过这种方式,您可以将传入的 int
转换为最大值为 2^32 - 1
unsigned int