You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中大数取模结果异常:long溢出导致错误值

为什么long类型相乘后取模结果不符合预期?

问题代码

long a = (long) 10e9+7;
long b = (a * a);

System.out.println("b is " + b);
System.out.println("b%a is " + (b%a));

System.out.println();

BigInteger A = BigInteger.valueOf((long) 10e9+7);
BigInteger B = A.multiply(A);

System.out.println("B is " + B.longValue());
System.out.println("B.mod(A) is " + B.mod(A));

输出结果

b is 7766279771452241969
b%a is 6015846137   ///->>> why ?? overflow 

B is 7766279771452241969 //// -> should not overflow 
B.mod(A) is 0

原因分析

  • long类型的溢出本质:Java中long是64位有符号整数,最大值为9223372036854775807(约9.2×10^18)。你的代码里a的值是10000000007((long)10e9将double类型的10000000000转为long,加7后得到),它的平方是100000000140000000049,这个数值远大于long的最大值,执行a * a时直接触发整数溢出。
  • 溢出后的数值是截断值:Java对整数溢出不会抛出异常,只会保留结果的低64位二进制位,因此b存储的是溢出截断后的错误值,而非真实的a*a。此时用这个错误值对a取模,结果自然不是0——因为它已经不再是a的整数倍了。
  • BigInteger的正确处理:BigInteger是任意精度的整数类型,能完整存储超大数值,不会发生溢出,因此B是a*a的真实值,B.mod(A)计算真实平方值对a取模,结果必然为0。而B.longValue()只是将高精度数值强制转换回long,此时同样会触发截断,得到和b一致的溢出值,但这只是转换后的结果,BigInteger内部始终保存着正确的完整数值。

内容的提问来源于stack exchange,提问作者Pawan Patel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 00:00:16