为什么相同的32位浮点数在JavaScript和Rust中不同?

在 JavaScript 中,38_579_240_960转换为 32 位浮点数时不会改变:

console.log(new Float32Array([38_579_240_960])[0]); // 38579240960

回答

虽然38,579,240,960能够准确地表示为 IEEE-754 32 位浮点数,但尾随960并不重要。24 位尾数只能表示7有意义的数字。上下可表示的下一个值是38,579,245,05638,579,236,864。因此,该数字38,579,240,960是数万个范围内最接近的可表示值。

因此,即使您添加1000到该值,两种语言都不会更改其输出:

38579240960
38579240960
38579240000

所以区别在于 JavaScript 打印出所表示的确切值,而 Rust 仅打印出最小数字来唯一地表达它。

如果你想让 Rust 的输出看起来像 JavaScript 的,你可以像这样指定精度(playground):

println!("{:.0}", 38579240960f32); // display all digits up until the decimal

我不一定会说,但是 Rust 的默认格式的一个优点是您不会对精确度产生错误的感觉。

也可以看看:

  • 如何以所有可用精度打印 Rust 浮点数?
  • Rust:用最少的小数点格式化浮点数
  • 这是 IEEE-754 浮点数的错误陈述。IEEE-754 标准很明确:每个浮点数据精确地代表一个数字或一个 NaN。“尾随 960”**是**重要的,它**用于算术,并且**确实**确定用它运算的结果。将浮点数视为近似值是错误的。他们是准确的。**运算**近似于实数运算;操作有效地将理想结果四舍五入到最接近的可表示数字……

回答

您的代码片段并不等效。JS 打印f64,Rust 打印f32.

JavaScript 没有 32 位浮点类型。当您Float32Array从中读取元素时,它会隐式转换为 64 位double,因为这是 JS 可以看到值的唯一方式。

如果你在 Rust 中做同样的事情,它会打印出相同的值:

println!("{}", 38_579_240_960_f32 as f64);
// 38579240960


以上是为什么相同的32位浮点数在JavaScript和Rust中不同?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>