使用awk除法运算时如何获取更多小数位并完整存储数值
关于awk除法运算的精度与存储问题
嘿,这个问题其实是awk默认输出格式在搞鬼,咱们先把核心点理清楚:
首先给你吃颗定心丸:你要的0.3515625是可以被awk的双精度浮点数精确存储的——因为它等于45/128,分母是2的整数次幂,属于二进制浮点数能精确表示的范畴。你看到输出变成0.351562,并不是变量p没存完整值,只是awk默认的print语句用了紧凑格式,截断了末尾的5。
先验证变量p的实际存储值
你可以用printf强制输出更高精度来确认这一点:
BEGIN{ x = 0.703125; p = x/2; printf "%.7f\n", p }
运行这个命令,你会得到完整的0.3515625,这说明p从一开始就完整存储了精确值,只是默认输出没显示全。
如何让输出默认显示完整精度
如果想让print语句默认就输出完整的小数位,有两种实用方法:
1. 修改awk的全局输出格式变量OFMT
OFMT是awk控制print输出浮点数的默认格式,默认值是"%.6g"(只保留6位有效数字)。你可以把它改成更高精度的格式,比如:
BEGIN{ OFMT = "%.7f"; x = 0.703125; p = x/2; print p }
这样运行后,print就会输出完整的0.3515625了。
2. 用printf灵活控制输出精度
如果只是特定场景需要高精度输出,直接用printf指定小数点后的位数更灵活,比如:
BEGIN{ x = 0.703125; p = x/2; printf "%.10f\n", p }
这会输出0.3515625000,你可以根据自己的需求调整位数。
额外提个醒:不是所有小数都能精确存储
需要注意的是,只有当小数能写成k/(2^n)(k和n都是整数)的形式时,才能被二进制浮点数精确存储。比如0.1就不行,它在二进制里是无限循环的,这时候无论怎么调精度,都只能得到近似值。但你的案例里的两个数都属于可精确表示的,所以完全不用担心存储丢失的问题。
内容的提问来源于stack exchange,提问作者JFS31
相关产品推荐
相关产品推荐

