【发布时间】:2016-03-27 06:41:19
【问题描述】:
我有两个变量(test1 和 test2),都是无符号的。
我需要检查其中哪个更大。
我试图了解如果发生溢出会发生什么。
我的第一个测试是使用 uint8_t (char) 数据类型完成的:
#include <stdio.h>
#include <stdint.h>
#include <math.h>
int main()
{
uint8_t test1 = 0;
printf("test1 = %d\n", test1);
uint8_t test2 = pow(2, 8 * sizeof(test1)) - 1; //max holdable value of uint8_t
printf("test2 = %d\n", test2);
uint8_t test3 = test1 - test2;
printf("test1 - test2 = %d\n", test3);
if ((test1 - test2) == 0)
printf("test1 == test2\n");
if ((test1 - test2) > 0)
printf("test1 > test2\n");
if ((test1 - test2) < 0)
printf("test1 < test2\n");
if (test3 == 0)
printf("test1 == test2\n");
if (test3 > 0)
printf("test1 > test2\n");
if (test3 < 0)
printf("test1 < test2\n");
return 0;
}
输出:
test1 = 0
test2 = 255
test1 - test2 = 1
test1 < test2
test1 > test2
什么?进行减法并将其保存在变量中,然后检查它,不同于动态检查减法吗?
我的第二个测试是使用 uint32_t (long) 数据类型完成的:
#include <stdio.h>
#include <stdint.h>
#include <math.h>
int main()
{
uint32_t test1 = 0;
printf("test1 = %d\n", test1);
uint32_t test2 = pow(2, 8 * sizeof(test1)) - 1; //max holdable value of uint32_t
printf("test2 = %lu\n", test2);
uint32_t test3 = test1 - test2;
printf("test1 - test2 = %d\n", test3);
if ((test1 - test2) == 0)
printf("test1 == test2\n");
if ((test1 - test2) > 0)
printf("test1 > test2\n");
if ((test1 - test2) < 0)
printf("test1 < test2\n");
if (test3 == 0)
printf("test1 == test2\n");
if (test3 > 0)
printf("test1 > test2\n");
if (test3 < 0)
printf("test1 < test2\n");
return 0;
}
输出:
test1 = 0
test2 = 4294967295
test1 - test2 = 1
test1 > test2
test1 > test2
什么???现在进行减法并将其保存在变量中,然后检查它,与在运行中检查减法相同吗?
所以 我期待无符号值之间的减法(没有显式转换)总是返回一个值> = 0。 但是在 IF 内做减法会导致意想不到的结果。
现在我很困惑。 有人可以向我解释这种行为吗?
【问题讨论】:
-
在 main 正文的第 3 行:
uint8_t test2 = pow(2, 8 * sizeof(test1)) - 1;这不是很明智,如果您将 2 的幂为8 * sizeof(test1),这将溢出uint8_t并获得零值.由于它是无符号的,溢出总是具有明确定义的值。因此,为了清楚起见,您应该写-1,而不是写这个。 -
您正在努力工作 - 您认为这个问题可以简化为仅分配测试 1 和测试 2,然后是产生您期望的结果的表达式示例不期望?这里似乎有大量多余的代码要趟过。
-
@ChrisBeck : 或
uint8_t test1 = ~0;而不是将负值分配给无符号类型,或者最好还是使用UCHAR_MAX或std::numeric_limits<uint8_t>::max() -
@user2104739:这里还有很多其他问题。特别是,将
%d与unsigned int一起使用是不行的。而且您显然也没有在编译时发出警告。如果你这样做了,编译器会为你解释很多这些问题。当您混合有符号和无符号整数时,编译器可能会做一些令人惊讶的事情,在这种情况下,如果您最终得到signed... 比较有符号和无符号... 是不好的,您应该采取措施确保0文字有正确的类型,static_cast结果是test1-test2等等,真正探索这个。