C 无符号长整型常量值与乘法值

C 无符号长整型常量值与乘法值,c,C,我尝试了下面的方法,似乎“测试”的结果是错误的值。2500*2500*2500==156500000,为什么下面的操作会导致不同的结果 unsigned long long int test = 2500*2500*2500; fprintf(stderr, "*************** test = %lld, %llu\n", test, test); unsigned long long int test2 = 15625000000; fprintf(stderr, "*******

我尝试了下面的方法,似乎“测试”的结果是错误的值。2500*2500*2500==156500000,为什么下面的操作会导致不同的结果

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

2500*2500*2500
不是一个无符号长型,因为您要将其复制到一个无符号长型。乘法是用
int
s完成的,因此乘法的结果是
int
。当升级到
unsigned long
时,已经太晚了。Use
2500ULL

2500*2500*2500
不是无符号长字符,因为您要将其复制到无符号长字符。乘法是用
int
s完成的,因此乘法的结果是
int
。当升级到
unsigned long
时,已经太晚了。Use
2500ULL

2500*2500*2500
永远不会升级到
int
之后,因此发生的带符号溢出(顺便说一下,UB)会停止正确的计算

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

  • 通过强制转换-强制转换文本通常在编译时处理,并且没有运行时开销:

    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
    是非法的。)


  • 2500*2500*2500
    永远不会升级到
    int
    之后,因此发生的有符号溢出(顺便说一下,UB)会停止正确的计算

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

  • 通过强制转换-强制转换文本通常在编译时处理,并且没有运行时开销:

    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
    是非法的。)


  • 可能是因为它是在运行时计算的,而您的32位计算机因某种原因无法使用64位值而溢出?请尝试将
    ULL
    添加到表达式中的
    2500
    常量中的至少一个。可能是因为它是在运行时计算的,而您的32位计算机因无法使用64位值而溢出出于某种原因,请尝试将
    ULL
    添加到表达式中的
    2500
    常量中的至少一个。值得指出的是,您只需要为第一个常量添加后缀,因为如果一个操作数是
    无符号长
    类型,那么另一个操作数将被提升。值得指出的是,您只需要为第一个常量添加后缀,因为如果一个操作数是
    无符号长
    类型,那么另一个操作数将被提升。