关于《每位计算机科学家都应了解的浮点数》中ulp误差计算的疑问
解开浮点数ULP计算的困惑:你踩了「量级混淆」的坑
嘿,我太懂这种盯着公式算出来的结果和原文对不上的挫败感了!核心问题其实很简单:你混淆了不同量级浮点数的ULP大小——ULP可不是固定不变的常数,它跟着数值的量级走,这是很多刚啃 Goldberg 那篇经典论文的人都会踩的坑。
让我一步步给你掰明白:
1. 先把ULP的本质搞清楚
ULP(最后一位的单位)的定义是:给定一个浮点数,它旁边相邻的两个可表示浮点数之间的差值。对于IEEE 754二进制浮点数来说,ULP的大小完全由数值的指数位(也就是数值的量级)决定:
- 如果一个数落在
[2^k, 2^(k+1))这个区间里,单精度浮点数的ULP就是2^(k-23),双精度是2^(k-52) - 计算误差对应的ULP数量,正确公式是:
|计算结果 - 真实值| / 真实值所在区间的ULP
2. 你的计算错在哪?
你用 |0.02 - 0.017| * 100 = 0.3ulps 来算,这犯了两个关键错误:一是把十进制的“末位单位”和二进制ULP的概念搞混了,二是错误地用缩放后的数值来计算,完全忽略了原始值(0.17)的量级对应的ULP大小。
回到原文的例子:
- 真实值是0.17,计算结果是0.2(也就是你说的0.02×10),两者差值是0.03
- 原文在这个保护位示例里,应该是用了特定精度的浮点数模型(比如十进制3位有效数字,或者低精度二进制),在这个模型下,0.17所在量级的ULP是0.001——这样0.03的误差刚好就是30个ULP(0.03 / 0.001 = 30)
你之前用缩放后的0.017和0.02计算,相当于把数值压到了0.01-0.02的量级,这个量级的ULP和0.1-0.2量级的ULP根本不是一回事,结果自然对不上。
3. 关键要点记牢
- ULP不是固定值,数值量级越大,ULP越大,反之越小
- 计算误差的ULP数量时,必须用真实值所在区间的ULP做除数,不能随便换量级计算
- 原文的例子是针对0.17这个量级的浮点数精度来算的,和你之前套用的公式场景完全不同,这就是你困惑的根源
要是还没搞懂,再回头看看论文里关于ULP和浮点数表示的基础章节,把“量级决定ULP大小”这个点刻进脑子里,下次就不会踩这个坑啦!
内容的提问来源于stack exchange,提问作者Kay
相关产品推荐
相关产品推荐

