我尝试了下面的内容,似乎'test'导致了错误的值。 2500 * 2500 * 2500 == 15625000000,为什么以下操作导致不同的结果?
unsigned long long int test = 2500*2500*2500;
fprintf(stderr, "*************** test = %lld, %llu\n", test, test);
unsigned long long int test2 = 15625000000;
fprintf(stderr, "*************** test2 = %lld, %llu\n", test2, test2);
结果:
*************** test = -1554869184, 18446744072154682432
*************** test2 = 15625000000, 15625000000
答案 0 :(得分:3)
2500 * 2500 * 2500
永远不会提升到int
之后,因此发生的签名溢出(顺便说一句,UB)会阻止执行正确的计算。
要允许它,您必须告诉编译器您的文字属于特定类型。有两种方法可以做到这一点:
通过强制转换 -casting文字通常在编译时处理,并且没有运行时开销:
unsigned long long int test = (unsigned long long int)2500 * (unsigned long long int)2500 * (unsigned long long int)2500;
请注意,演员是在被乘数上单独执行的。如果操作的结果是强制转换的(例如(unsigned long long int)(2500 * 2500 * 2500)
),则转换为时已太晚,无法保存数据。
后缀:
unsigned long long int test = 2500ULL * 2500ULL * 2500ULL;
这在运行时与文字的转换一样高效,但根据使用情况可能更容易或更难阅读。后缀必须直接应用于文字(它不能应用于操作的结果,因此(2500 * 2500 * 2500)ULL
是非法的。)
答案 1 :(得分:2)
2500*2500*2500
不是unsigned long long,因为你将它复制到unsigned long long。乘法是用int
s完成的,因此乘法的结果是int
。升级到unsigned long long
时,已经太晚了。使用2500ULL
。