如何判断浮点数运算结果中可靠的十进制位数?
我正试图提升自己判断浮点数短运算后正确十进制位数的能力,尤其希望能通过分析运算过程,建立一套确定可靠位数的流程。
我不寻求使用多精度包的方法,而是希望仅依靠IEEE标准(单精度或双精度)、所用算术操作及输出结果,推断正确的十进制位数。
目前我的方法是依次询问以下问题:
- 使用的是哪种IEEE标准?单精度有8个可用十进制位,双精度则有16个可用十进制位。
- 基于所用IEEE标准,输入在计算机中的存储形式是怎样的?
- 运算中是否包含减法?(若是,这是易出错的环节,因为减法的条件数不佳)
- 输出结果中包含多少个零(小数点前后)?
最终公式:
正确十进制位数 = IEEE标准可用位数 - 输出中的零的数量
示例
以下示例用于说明我的问题,所有示例均询问:“输出结果中有多少位十进制数是正确的?”
示例1
x = 900000.00000 y = 900000.00012 x - y Output: -0.00011999998241662979
我的解法:
此处使用Julia默认的双精度标准,有16个可用位数。从计算机角度看,x和y近似为(9×10⁵)。从人类视角计算x-y得到(-000000.00012),包含9个零(小数点前后),因此正确位数为16-9=7位。即无论计算机输出的(-0.00011999998241662979)有多精确,仅前7位(-0.000119)是正确的,其余均不可靠。
这合理吗?我不确定如何处理符号位(+或-),这是否会导致正确位数变为(-0.00011)?
示例2
x = 9876.34f0 sqrt(x) - sqrt(x + 1) Output: -0.005027771f0
我的解法:
此处使用单精度标准(由“f”标识),有8个可用位数。从计算机角度看,x近似为(9.87634×10³)。难以确定a=sqrt(x)和b=sqrt(x+1)在计算机中的存储形式。估算可知,a=sqrt(9.87634×10³)=9.87634(1/2)×10(3/2),因此a∈(10¹,10²);b=sqrt(x+1)=sqrt(9.87634×10³+1.0×10⁰)=sqrt(9.87734×10³)=9.87734(1/2)×10(3/2),a和b均处于(3.×10¹,3.×10²)区间内。从此处开始我难以推进……我的方法是查看输出(-0.005027771f0),发现包含3个零(小数点前后),因此判断正确位数为8-3=5位,即计算机输出的前5位(-0.0050)正确,其余不可靠。
我认为此解法不正确,因为它忽略了从人类视角看的a-b=(9.87634(1/2)×10(3/2))-(9.87734(1/2)×10(3/2))的减法运算,而这在第一个示例中帮我得到了正确的零的数量。
更新(2025年1月27日)
首先感谢各位的解答。我认为自己正朝着正确方向前进。基于现有评论,我制作了一个带注释的Julia笔记本示例(HMDCIRO.jl),相关PDF文档比README更适合作为参考。
内容的提问来源于stack exchange,提问作者L. Perasolo

