当uint64 = uint8 * uint8时溢出

时间:2016-10-14 07:18:29

标签: c++

我尝试以下代码:

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?是不是?

我想搜索谷歌的一些提示,但我不知道应该使用哪个关键词。

由于

4 个答案:

答案 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。