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