unsigned long long int常量值与乘法值

时间:2012-07-02 05:28:16

标签: c

我尝试了下面的内容,似乎'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

2 个答案:

答案 0 :(得分:3)

2500 * 2500 * 2500永远不会提升到int之后,因此发生的签名溢出(顺便说一句,UB)会阻止执行正确的计算。

要允许它,您必须告诉编译器您的文字属于特定类型。有两种方法可以做到这一点:

  1. 通过强制转换 -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)),则转换为时已太晚,无法保存数据。

  2. 后缀

    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