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

基于舍入π的算术计算中x1与x2仅特定precision相等的原因咨询

为什么只有特定precision值下x1 == x2成立?

咱们先把代码里的逻辑拆明白,再一步步推导背后的原因——你观察到的x1+x2始终等于PI/precision是个非常关键的线索,先从这里入手:

1. 先搞懂变量到底代表什么

先明确几个核心变量的实际含义:

  • PI = (int) Math.round(Math.PI * precision):这其实是把π放大precision倍后四舍五入取整,反过来PI/precision就是π四舍五入到precision位小数的近似值(比如precision=2时,π*2≈6.28,取整后是6,6/2=3.0就是π保留2位小数的近似值)。
  • x1 = makePrecise(Math.PI / 2):把π/2也四舍五入到precision位小数的结果。
  • x2 = makePrecise(PI / precision - Math.PI / 2):用π的近似值减去真实的π/2,再把这个差值四舍五入到precision位小数。

2. 为什么x1 + x2永远等于PI/precision?

makePrecise(num)的本质就是把num乘以precision后四舍五入,再除以precision,说白了就是给num保留precision位小数(或者说精确到1/precision的精度)。

假设a = Math.PI/2,b = PI/precision - Math.PI/2,那显然a + b = PI/precision——这个值是个整数除以precision的分数,是precision位小数的精确值(比如precision=3时就是9/3=3.0)。

现在看a*precision + b*precision = (a+b)*precision = PI,这是个整数。如果a*precision的整数部分是m,小数部分是f(0≤f<1),那b*precision的整数部分就是PI - m,小数部分是1 - f(因为两个小数部分加起来刚好是1,才能让总和是整数)。

那四舍五入之后:

  • 如果f < 0.5,a*precision四舍五入是m,b*precision的小数部分1-f > 0.5,四舍五入是(PI - m) + 1,加起来就是m + (PI - m) +1 = PI;
  • 如果f > 0.5,a*precision四舍五入是m+1,b*precision的小数部分1-f <0.5,四舍五入是PI - m,加起来也是(m+1)+(PI -m)=PI;
  • 哪怕f=0.5(Java用的是银行家舍入,小数部分0.5时取最近的偶数),两者四舍五入后的和依然是PI——比如a*precision=4.5(四舍五入为4,因为4是偶数),b*precision=4.5(四舍五入为4),加起来8,刚好等于PI=8。

所以把这两个四舍五入的结果除以precision,加起来就是PI/precision,这就是为什么x1+x2永远等于这个值。

3. 为什么只有特定precision下x1 == x2?

x1 == x2等价于它们四舍五入后的整数部分相等(因为都除以precision),也就是:

round(Math.PI/2 * precision) == round( (PI/precision - Math.PI/2) * precision )

把右边化简一下,就是round(PI - Math.PI/2 * precision),而PI是round(Math.PI * precision),我们设Q = Math.PI * precision,那PI = round(Q),代入后问题就变成:

round(Q/2) == round( round(Q) - Q/2 )

再设round(Q) = Q + ε,这里的ε就是四舍五入的误差,范围是-0.5 ≤ ε < 0.5(当Q是半整数时,比如3.5,ε就是+0.5;2.5的话ε是-0.5,因为Java取偶数)。代入后式子变成:

round(Q/2) == round(Q/2 + ε)

这个等式成立与否,完全看Q/2的小数部分和ε的大小:

  • 如果Q/2的小数部分离0.5很远,比如0.1或者0.8,那ε的波动(最多±0.5)不会改变四舍五入的结果,等式就成立;
  • 如果Q/2的小数部分接近0.5,比如0.49或者0.51,那ε的正负就会让四舍五入的结果跳变,等式就不成立。

但Q = Math.PI * precision,π是无理数啊!它的小数部分是无限不循环的,所以π*precision的小数部分也是完全无规律的——随着precision增大,Q的小数部分不会重复出现固定模式,ε的取值也就毫无规律,自然x1 == x2的precision值看起来就没什么明显规律了。

举两个实际例子:

  • precision=2时,Q=π*2≈6.28,ε=-0.28,Q/2≈3.14(小数部分0.14),Q/2+ε≈2.86(小数部分0.86),两者四舍五入都是3,所以x1=x2=1.5;
  • precision=3时,Q=π*3≈9.424,ε=-0.424,Q/2≈4.712(小数部分0.712,四舍五入为5),Q/2+ε≈4.288(小数部分0.288,四舍五入为4),所以x1≈1.666,x2≈1.333,两者不相等。

总结一下

  • x1 + x2始终等于PI/precision,是因为两个数四舍五入后的误差刚好抵消,加起来等于精确的近似值;
  • 只有特定precision下x1 == x2,是因为π的无理数特性导致π*precision的小数部分完全无规律,进而让四舍五入误差是否会改变Q/2的舍入结果也没有固定规律。

内容的提问来源于stack exchange,提问作者Gaurang Tandon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:10:07