V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
sillydaddy
V2EX  ›  问与答

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

  •  
  •   sillydaddy · 2021-01-26 10:40:11 +08:00 · 1446 次点击
    这是一个创建于 1430 天前的主题,其中的信息可能已经有所发展或是发生改变。
    计算机的浮点数只有有限精度,浮点运算会损失精度,我就遇到了一个例子:
    已知 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 的值,让经过运算后的浮点结果更精确吗?
    6 条回复    2021-01-26 11:47:17 +08:00
    shintendo
        1
    shintendo  
       2021-01-26 10:47:01 +08:00
    浮点精度看有效数字,你放大也没用吧
    walsh
        2
    walsh  
       2021-01-26 10:58:00 +08:00
    FLT_EPSILON DBL_EPSILON
    详情《数值分析》
    agagega
        3
    agagega  
       2021-01-26 11:04:10 +08:00 via iPhone
    浮点数的误差很多来自两点:
    1. 有效数字不同,也就是大数和小数做运算的时候。因为做运算的时候要把指数对齐,所以理论上你放大还是不放大没有什么区别
    2. 一些数在二进制里无法精确表示
    tonyrft
        4
    tonyrft  
       2021-01-26 11:05:04 +08:00
    如果真的想要高精度用计算机代数系统就行了
    vivoapex
        5
    vivoapex  
       2021-01-26 11:30:55 +08:00
    参考《深入理解计算机系统》,我花了两周才把整数和浮点数搞定
    UN2758
        6
    UN2758  
       2021-01-26 11:47:17 +08:00
    不能,由于 IEEE754 规定的尾码长度有限,遇到无法用 2 的 n^-1 表示的数时,误差就一定存在,你的放大操作是放大了阶码,没用
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5264 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 09:29 · PVG 17:29 · LAX 01:29 · JFK 04:29
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.