为什么相同的 32 位浮点数在 JavaScript 和 Rust 中不同?
Why are the same 32-bit floats different in JavaScript and Rust?
在JavaScript中,38_579_240_960
转换为32位浮点数时不变:
console.log(new Float32Array([38_579_240_960])[0]); // 38579240960
但是 in Rust,四舍五入为 38579240000
。怎么样?
fn main() {
println!("{}", 38_579_240_960_f32);` // 38579240000
}
虽然 38,579,240,960
可以准确表示为 IEEE-754 32 位浮点数,但尾部 960
并不重要。 24位的尾数只能表达约7
个有意义的数字。上方和下方的下一个可表示值是 38,579,245,056
和 38,579,236,864
。因此,数字 38,579,240,960
是跨越数万的范围内最接近的可表示值。
因此,即使您将 1000
添加到该值,两种语言都不会更改其输出:
38579240960
38579240000
所以不同之处在于 JavaScript 打印出所表示的确切值,而 Rust 仅打印出最小数字以唯一地表达它。
如果您希望 Rust 输出看起来像 JavaScript 的,您可以像这样指定精度 (playground):
println!("{:.0}", 38579240960f32); // display all digits up until the decimal
38579240960
我不会把其中一个称为 right 或 wrong ,但是 Rust 的默认格式的一个优点是你不需要得到一种错误的精确感。
另请参阅:
- How do I print a Rust floating-point number with all available precision?
- Rust: Formatting a Float with a Minimum Number of Decimal Points
您的代码片段不等同。 JS 打印 f64
,而 Rust 打印 f32
.
JavaScript 没有 32 位浮点类型。当您从 Float32Array
中读取一个元素时,它会隐式转换为 64 位 double
,因为这是 JS 可以看到该值的唯一方式。
如果您在 Rust 中执行相同的操作,它会打印相同的值:
println!("{}", 38_579_240_960_f32 as f64);
// 38579240960
在JavaScript中,38_579_240_960
转换为32位浮点数时不变:
console.log(new Float32Array([38_579_240_960])[0]); // 38579240960
但是 in Rust,四舍五入为 38579240000
。怎么样?
fn main() {
println!("{}", 38_579_240_960_f32);` // 38579240000
}
虽然 38,579,240,960
可以准确表示为 IEEE-754 32 位浮点数,但尾部 960
并不重要。 24位的尾数只能表达约7
个有意义的数字。上方和下方的下一个可表示值是 38,579,245,056
和 38,579,236,864
。因此,数字 38,579,240,960
是跨越数万的范围内最接近的可表示值。
因此,即使您将 1000
添加到该值,两种语言都不会更改其输出:
38579240960
38579240000
所以不同之处在于 JavaScript 打印出所表示的确切值,而 Rust 仅打印出最小数字以唯一地表达它。
如果您希望 Rust 输出看起来像 JavaScript 的,您可以像这样指定精度 (playground):
println!("{:.0}", 38579240960f32); // display all digits up until the decimal
38579240960
我不会把其中一个称为 right 或 wrong ,但是 Rust 的默认格式的一个优点是你不需要得到一种错误的精确感。
另请参阅:
- How do I print a Rust floating-point number with all available precision?
- Rust: Formatting a Float with a Minimum Number of Decimal Points
您的代码片段不等同。 JS 打印 f64
,而 Rust 打印 f32
.
JavaScript 没有 32 位浮点类型。当您从 Float32Array
中读取一个元素时,它会隐式转换为 64 位 double
,因为这是 JS 可以看到该值的唯一方式。
如果您在 Rust 中执行相同的操作,它会打印相同的值:
println!("{}", 38_579_240_960_f32 as f64);
// 38579240960