今天在写wasm时,遇到一个f32四舍五入精度不对的问题。
示例代码见下:
// rustc 1.50.0 (cb75ad5db 2021-02-10)
fn main() {
println!("{:.2}",0.0050_f32); // 0.00
println!("{:.2}",0.0051_f32); // 0.01
println!("{:.2}",0.0050_f64); // 0.01
println!("{:.2}",0.0051_f64); // 0.01
}
发现wasm函数出来的结果,当传入值类型为f32,值是0.005时,保留两位小数,居然是0.00。 只有当值大于0.005时,譬如0.0051时,才会正常进位变成0.01。而f64就没有这种问题。
之所以采用wasm去实现一些计算,初衷也是为了规避js浮点数精度不对的问题,没想到在Rust上也踩到了坑。 起初怀疑是浏览器的问题,在Playground试了一把,还是一样的情况。 然后本地又做了测试,没料到依然同样的错误。
瞅了下标准库的f32和fmt,也没有找到相关的资料。 坛子里有大佬能帮忙分析下么,或是给个资料链接也好。
1
共 5 条评论, 1 页
评论区
写评论参考ieee754对浮点数的标准定义
的确是这个原因。惭愧,感觉对不起大学老师。
又去看了下f32的Display Trait实现,确实std做了很多处理。
放大精度后,显示的就是这几个值。
--
👇
daleione: 这块和语言没关系吧。这个属于float的计算问题。 float 不能准确表示 0.0050,存在一定的差值。 float64 里面, 0.0050 二进制表示: 0.005000000000000000104083408558608425664715468883514404296875
float32 里面,0.0050 二进制表示: 0.004999999888241291046142578125
所以,这里四舍五入,float32 变成 0.00 了
你在任何语言里,应该都会得到同样的答案。
这块和语言没关系吧。这个属于float的计算问题。 float 不能准确表示 0.0050,存在一定的差值。 float64 里面, 0.0050 二进制表示: 0.005000000000000000104083408558608425664715468883514404296875
float32 里面,0.0050 二进制表示: 0.004999999888241291046142578125
所以,这里四舍五入,float32 变成 0.00 了
你在任何语言里,应该都会得到同样的答案。
mark
给你捞了个第一行的汇编