让人困惑的浮点精度和误差

2021-01-26 10:40:11 +08:00
 sillydaddy
计算机的浮点数只有有限精度,浮点运算会损失精度,我就遇到了一个例子:
已知 A,B 两点坐标分别为(10000000.0, 0, 0), (10000000.0, 0.001, 0),求 AB 线段的长度。
解法 1: 直接求向量 A-B=(0,0.001,0)的长度,得到结果是 0.001
解法 2: 由于 A 、B 和原点 O 构成直角三角形,使用勾股定理,使用|AO|*|AO| - |BO|*|BO| = |AB|*|AB|,求得|AB|是 0
其中,解法 2 由于在大数的乘法运算后,再做减法运算,导致损失了精度。

那么,现在我想解二次方程 a*x*x+b*x+c=0 的根:
用求根公式:x1,2=(-b±Δ)/(2*a),其中Δ=sqrt(b*b-4*a*c)
公式里面有浮点数的乘法,加减法,除法,所以比照上面举的例子,这里应该也会损失精度。

那么损失的精度是多少呢?
我注意到,方程系数 a,b,c 的值可以等比例放大,不影响理论上的计算结果,那么可以通过放大 a,b,c 的值,让经过运算后的浮点结果更精确吗?
1416 次点击
所在节点    问与答
6 条回复
shintendo
2021-01-26 10:47:01 +08:00
浮点精度看有效数字,你放大也没用吧
walsh
2021-01-26 10:58:00 +08:00
FLT_EPSILON DBL_EPSILON
详情《数值分析》
agagega
2021-01-26 11:04:10 +08:00
浮点数的误差很多来自两点:
1. 有效数字不同,也就是大数和小数做运算的时候。因为做运算的时候要把指数对齐,所以理论上你放大还是不放大没有什么区别
2. 一些数在二进制里无法精确表示
tonyrft
2021-01-26 11:05:04 +08:00
如果真的想要高精度用计算机代数系统就行了
vivoapex
2021-01-26 11:30:55 +08:00
参考《深入理解计算机系统》,我花了两周才把整数和浮点数搞定
UN2758
2021-01-26 11:47:17 +08:00
不能,由于 IEEE754 规定的尾码长度有限,遇到无法用 2 的 n^-1 表示的数时,误差就一定存在,你的放大操作是放大了阶码,没用

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/748405

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX