作者HuangTzHuan ()
看板C_and_CPP
标题Re: [问题] float 精准度观念问题
时间Fri Sep 28 11:51:48 2018
※ 引述《Feis (坐吃山空)》之铭言:
: 标题: Re: [问题] float 精准度观念问题
: 时间: Wed Sep 19 00:13:10 2018
[deleted]
:
: 要透过浮点数做运算时大概有三个步骤
:
: 1. 将要计算的数字转换成浮点数可精确表示的格子点 (可能产生误差)
: 2. 对这些在格子点上的数字们做运算
: 3. 将算出来的结果存在浮点数可精确表示的格子点上 (可能产生误差)
[deleted]
:
: ※ 编辑: Feis (140.122.83.198), 09/19/2018 00:47:44
: 推 cutekid: 大推(Y) 09/19 03:16
: 推 chchwy: 神解答 格子点的解释很好懂 09/19 08:03
: 推 sarafciel: 推格子点的解释 09/20 15:14
: 推 lovejomi: 针对那三个步骤,算的时候没有受到误差限制反而是算完 09/25 16:59
: → lovejomi: 之後3. 会因为要mapping to ieee754而产生误差 这边觉 09/25 16:59
: → lovejomi: 得很神奇 不知道cpu怎麽运算的 09/25 16:59
计算的部份 (2.) 也会有误差啊
除法除不尽的话本来就一定会有误差,就算加法乘法这种本来应该可以精确计算
也可能会有误差
举例来说,两个浮点数相乘时,小数以下部份可能会超过浮点数能表示的极限
超过的部份资讯就丢失了,这个部份就是误差
实务上 CPU 在设计时时会尽量减少计算误差,作法其实很简单,就是作弊
例如 x86 系列的 FPU 其实是 80-bit
所以在计算 float (32-bit) 或 double (64-bit) 的过程中就可以保留更多精确位
有兴趣的话可以看 IEEE754 extended precision formats 的部份
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 140.112.30.51
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1538106711.A.299.html
※ 编辑: HuangTzHuan (140.112.30.51), 09/28/2018 11:53:06
1F:推 LPH66: 这里还有一个衍生问题是当编译器最佳化把中间过程留在 FPU 09/28 18:21
2F:→ LPH66: 里的时候跟没有最佳化算一个就存回 double 这两种的结果 09/28 18:21
3F:→ LPH66: 就会因为这个问题而产生不同结果 09/28 18:22
4F:→ LPH66: 一个例子可以看这则久远之前的 gcc bug report 09/28 18:34
6F:→ remember: 不是这样讲,没有实作80bit浮点的硬体仍然能得到符合iee 10/03 02:45
7F:→ remember: e的结果 10/03 02:45
8F:→ remember: 加减乘的结果都是有限位所以没问题 10/03 02:46
9F:→ remember: 除法跟开根号则不同,精确度的规定是算出有限位的结果, 10/03 02:50
10F:→ remember: 和无限精确的结果,差距在一个ulp内(如果是round2even, 10/03 02:50
11F:→ remember: 则是半个ulp) 10/03 02:50
12F:→ remember: 浮点数是实数的有限位表达,根号3浮点化之後再自乘是无 10/03 02:54
13F:→ remember: 法变回精确的3的,随着运算误差有可能会变大,这跟演算 10/03 02:54
14F:→ remember: 法的稳定度有关 10/03 02:54