3 * 1000000000 overflows as an int, but the variable is long long. Why?

时间:2017-03-22 18:50:12

标签: c++ long-long

I have a simple c++ app that performs the following calculations

long long calcOne = 3 * 100000000;     // 3e8, essentially
long long calcTwo = 3 * 1000000000;    // 3e9, essentially
long long calcThree = 3 * 10000000000; // 3e10, essentially

If I write the result of each calculation I get the following output:

calcOne = 300000000
calcTwo = -1294967296
calcThree = 30000000000

So why does the second calculation fail? As far as I can tell it is within the limits of a long long type (calcThree was larger...).

I am using Visual Studio 2015 on Windows 10. Thanks in advance.

4 个答案:

答案 0 :(得分:7)

默认情况下,整数常量为int s。

1000000000

这可以适合int。因此,此常量被解析为int。但是将它乘以3溢出int。

10000000000

这对于int来说太大了,所以这个常量是long long,因此得到的乘法不会溢出。

解决方案:明确使用long long常量:

long long calcOne = 3 * 100000000LL;     // 3e8, essentially
long long calcTwo = 3 * 1000000000LL;    // 3e9, essentially
long long calcThree = 3 * 10000000000LL; // 3e10, essentially

答案 1 :(得分:2)

您对结果执行的操作不会影响计算结果的方式。因此,将结果存储在long long中的事实不会改变您在第二行代码中乘以的数字不是long long的事实,因此它们会溢出。在第三行代码中,常量为long long,因此乘法在long long s上执行。

答案 2 :(得分:1)

编译器看到了这个

long long calcOne = (int) 3 * (int) 100000000;     // 3e8, essentially
long long calcTwo = (int) 3 * (int) 1000000000;    // 3e9, essentially
long long calcThree = (int) 3 * (long long) 10000000000; // 3e10, essentially

因此,calcTwo右手值被推断为int类型,然后过度流动。你认为过流是一个负面的长期。

long long calcOne = 3LL * 100000000LL;     // 3e8, essentially
long long calcTwo = 3LL * 1000000000LL;    // 3e9, essentially
long long calcThree = 3LL * 10000000000LL; // 3e10, essentially

为了避免将来出现这种情况,请明确静态值的类型。告诉编译器一个数字是long long帖子用LL修复它。

答案 3 :(得分:0)

大多数编程语言按大小对数字类型进行排名。数值表达式的大小/等级/类型(通常)是表达式中排名最高的值的类型。

示例:int * double - >双

您的计划有: long long int = int * int。

发生的事情是int * int的结果是int。因此,您的程序将首先乘以并以有符号整数处理结果(最大值〜= 20亿,因此它包含在负数中)。然后,这个负值存储在long long int中。

3亿(你的第一次乘法)适合int。没问题。我猜第三个工作正常,因为编译器足够聪明,知道300亿不适合32位int并自动给它一个64位长的int。