为什么是215510 * 10000!= 2155100000?

时间:2013-12-22 08:17:31

标签: c++

我有以下代码:

UINT64 time1 = 215510*10000;
UINT64 time2 = (UINT64)(215510 * 10000);

当打印它们或在Watch中时,结果是:

time1 = 18446744071569684320
time2 = 18446744071569684320

其实我知道怎么做到这里。我们必须使用以下代码之一才能得到正确的答案(以下3个版本都可以):

UINT64 time3 = (UINT64)215510 * 10000;
UINT64 time4 = 215510 * (UINT64)10000;
UINT64 time5 = (UINT64)215510 * (UINT64)10000;

但为什么前两行不能给出正确答案?

3 个答案:

答案 0 :(得分:11)

这是因为你通过乘以两个结果大于32位的32位数来调用整数溢出。您需要先转换为64位,如您所示。

答案 1 :(得分:9)

因为像215510这样的文字常量通常标准C ++中的int(不是long)。它与Visual Studio无关(至少如果g++ - s有32位,它应该与GCC又名int的其他编译器相同),所以215510 * 10000是也是int。尝试215510L * 10000让一个被乘数为long(因此该产品也是long - 如果long - s仍为32位,则不会更改产品! ),甚至215510LL使其成为long long或使用明确的演员(int64_t)215510 ......

在您的平台上,int可能是32位。所以签名的INT_MAX2147483647(2 31 - 1)。

Keith Thompson正确地评论了

  

整数常量的类型是相应列表的第一个   其值可以表示。

per(C11标准§6.4.4.1项5或)C ++ 11标准§2.14.2项2.因此,在16位int - s和32位{{1}的实现上} -s long是一个215510字面常量(因为215510> 32767,它将是long ....)。

与我所认为的相反,文字积分常数的类型不是由它的后缀 - 或者缺乏它 - 单独定义,而是由它的值定义!

答案 2 :(得分:3)

在C ++中,非整数整数文字的类型为intlong intlong long int,无论哪个是第一个可以表示其值的文件。 (long long int是该语言的最新成员。)

可能在您的系统上,21551010000都是int类型,可能是32位类型。

表达式(通常)由它们自己评估,而不考虑它们出现的上下文。因此,表达式215510*10000被评估为int。由于数学结果超出INT_MAX,结果未定义,但可能是-2139867296

当该值转换为64位无符号类型时,它会回绕,产生18446744071569684320(略小于2 64 )。