C uint64\u t上的错误计算结果 上下文

C uint64\u t上的错误计算结果 上下文,c,linux,math,64-bit,C,Linux,Math,64 Bit,Debian 64位 我有这个密码 #include <stdlib.h> #include <stdio.h> #include <stdint.h> int main(int argc, char ** argv){ uint64_t b = 5000000000;/* 5 000 000 000 */ uint64_t a = (b*b)/2; printf("a = %llu\n",a); return 0; } #包

Debian 64位

我有这个密码

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>

int main(int argc, char ** argv){

    uint64_t b = 5000000000;/* 5 000 000 000 */
    uint64_t a = (b*b)/2;

    printf("a = %llu\n",a);

return 0;
}
#包括
#包括
#包括
int main(int argc,字符**argv){
uint64_t b=5000000000;/*5000*/
uint64_t a=(b*b)/2;
printf(“a=%llu\n”,a);
返回0;
}
问题 Javascript、我的手动计算器和我操作系统中的虚拟计算器给我的结果是1.25×10^19,而我上面的c程序给我的结果是a=3276627963145224192


我做错了什么?

您的
b*b
中间操作的值大于64位寄存器可以容纳的值,因此溢出

由于,
b(=5000000)>2^32
,因此,
b*b>2^64

而且,由于
5000000000*5000000000/2
永远无法放入64位变量中,如果不使用特殊方法(如使用数组表示数字),就无法在C中计算此值

此外,正如@Joachim Pileborg所建议的,您应该将
无符号长
值分配给
b
as

uint64\u t b=5000000000ull

#包括
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>

int main(int argc, char ** argv){

    uint64_t b = 5000000000LL;/* 5 000 000 000 */
    uint64_t a = (((uint64_t)b)*b)/2LL;

    printf("a = %llu\n",a);

return 0;
}
#包括 #包括 int main(int argc,字符**argv){ uint64_t b=5000000000LL;/*5000*/ uint64_t a=((uint64_t)b)*b)/2LL; printf(“a=%llu\n”,a); 返回0; }
uint64\u t
无法保存
b*b
的结果

b*b
的结果是2500000000000000000。这是25x10^18

但是
uint64\u t
可以保存最大值6553255926290448384。因此,在
b*b
操作中会发生溢出


由于此溢出,您无法获得实际结果

仅仅提供代码而不做任何解释是没有什么帮助的。这种强制转换是不必要的。另外,它仍然给出了错误的结果。结果不应该是
1.25*10^19
?很好,你是对的,我错过了一个零:)那么一个零会使结果溢出…:-)
5000000000>2^32
,所以
5000000000^2>2^64
,很容易看到溢出