识别和避免舍入错误
当用数值逼近一个值时,请记住浮点结果可能对所使用的精度很敏感。此外,浮点结果很容易出现舍入错误。以下方法可以帮助您识别和避免错误的结果。
尽可能使用符号计算
执行计算象征性地推荐使用,因为精确的符号计算不容易出现舍入错误。例如,标准数学常数在symbolic Math Toolbox™中有自己的符号表示:
π信谊(π)
Ans = 3.1416 Ans = PI
避免不必要地使用数值近似。浮点数近似于常数;它不是常数本身。使用这种近似,你可能得到不正确的结果。例如,亥维赛
特殊的函数返回不同的正弦结果信谊(π)
sin的数值近似π
:
亥维赛(sin(信谊(π)))亥维赛(sin (pi))
Ans = 1/2 Ans = 1
执行计算与提高精度
黎曼假设指出黎曼ζ函数的所有非平凡零ζ(z)有相同的实部吗ℜ(z) = 1/2.为了找到Zeta函数的可能零点,画出它的绝对值|ζ(1/2 +iy)|.下面的图显示了Zeta函数的前三个非平凡根|ζ(1/2 +iy)|.
信谊yFplot (abs(zeta(1/2 + i*y)), [0 30])
使用数值求解器vpasolve
来近似这个Zeta函数的前三个零:
Vpasolve (zeta(1/2 + i*y), y, 15) Vpasolve (zeta(1/2 + i*y), y, 20) Vpasolve (zeta(1/2 + i*y), y, 25)
Ans = 14.134725141734693790457251983562 Ans = 21.022039638771554992628479593897 Ans = 25.010857580145688763213790992563
现在,考虑相同的函数,但稍微增加实部,
.根据黎曼假设,这个函数对于任何实值都没有零y.如果你使用vpasolve
用10个有效的十进制数字,求解器找到以下(不存在的)Zeta函数的零:
旧=数字;数字(10)vpasolve(zeta(1000000001/2000000000 + i*y), y, 15)
Ans = 14.13472514
增加位数表示结果不正确。函数 任何实值都没有014 <y< 15:
数字(15)vpasolve(zeta(1000000001/2000000000 + i*y), y, 15)数字(旧)
Ans = 14.1347251417347 + 0.000000000499989207306345i
为了进一步的计算,恢复默认位数:
数字(旧)
比较符号和数字结果
带半整数下标的贝塞尔函数返回精确的符号表达式。用浮点数近似这些表达式会产生非常不稳定的结果。例如,以下贝塞尔函数的精确符号表达式为:
B = besselj(53/2, sym(pi))
B = (351*2^(1/2)*(119409675/pi^4 - 20300/pi^2 - 315241542000/pi^6…+ 445475704038750/pi^8 - 366812794263762000/pi^10 +…182947881139051297500/pi^12 - 55720697512636766610000/pi^14…+ 10174148683695239020903125/pi^16 - 1060253389142977540073062500/pi^18…+ 57306695683177936040949028125/pi^20 - 1331871030107060331702688875000/pi^22…+ 8490677816932509614604641578125/pi^24 + 1))/pi^2
使用vpa
用10位数的精度来近似这个表达式:
vpa (B, 10)
Ans = -2854.225191
现在,使用浮点形参调用贝塞尔函数。这两个近似之间的显著差异表明一个或两个结果都是不正确的:
besselj(53/2π)
Ans = 6.9001e-23
提高数值工作精度以获得更精确的近似B
:
vpa (B, 50)
Ans = 0.000000000000000000000069001456069172842068862232841396473796597233761161
绘制函数或表达式
绘制结果可以帮助您识别不正确的近似值。例如,以下贝塞尔函数的数值近似返回:
B = besselj(53/2, sym(pi));vpa (B, 10)
Ans = -2854.225191
画出贝塞尔函数的值x
周围53/2
.函数图显示近似是不正确的:
信谊xFplot (besselj(x, sym(pi)), [26 27])