我尝试以下代码:
UINT a = 32768;
UINT b = 32768;
UINT64 c = a * b * 4; // c = 0, overflow...;
UINT64 d = (UINT64)a * (UINT64)b * 4; // d = 4294967296, the right answer;
为什么UINT64 c = a * b * 4会溢出?
我认为a * b * 4首先会保留一个临时UINT值,然后分配给参数c?是不是?
我想搜索谷歌的一些提示,但我不知道应该使用哪个关键词。
由于
答案 0 :(得分:3)
UINT a = 32768;
UINT b = 32768;
UINT64 c = a * b * 4;
评估为
UINT a = (UINT) 32768;
UINT b = (UINT) 32768;
UINT64 c = (UINT) a * (UINT) b * (int) 4;
如果UINT
没有足够的空间来存储UINT*UINT
,则会出现溢出。
您可以通过将UINT
中的一个投放到UINT64
来解决此问题,如下所示:
UINT64 c = (UINT64) a * b * 4;
答案 1 :(得分:2)
相同的原因
double x=1/2;
将为0,但
double y=double(1)/2;
将是0.5
。
除非您将其中一个操作数强制为所需的最终类型,否则所有操作数的最大精度都将计算,并且只有在转换为目标类型之后才会计算。
在这种情况下,所有内容都以32位精度计算,溢出发生在之前转换为64位。
答案 2 :(得分:0)
在c的uint64中,它的右侧被自动指定为uint,因为A和B都是uint,之后它将答案分配给c(已经溢出)。为了确保不会发生这种情况,c中的一个变量也必须是uint64,然后它不会溢出。 这就是为什么int64 d工作,因为它也被分配。
答案 3 :(得分:0)
你的假设是正确的。因为a和b是UINT值,所以操作是作为UINT完成的,在* b * 4期间,它是2 ^ 32,它在32位UINT中溢出为0.结果只会转换为UINT64。