gpt4 book ai didi

rust - 为什么 Rust 只使用 16 位有效数字进行 f64 相等检查?

转载 作者:行者123 更新时间:2023-12-03 11:25:27 24 4
gpt4 key购买 nike

我有以下 Rust 代码:

use std::f64::consts as f64;

fn main() {
println!("Checking f64 PI...");
// f64::PI definition: https://github.com/rust-lang/rust/blob/e1fc9ff4a794fb069d670dded1a66f05c86f3555/library/core/src/num/f64.rs#L240
println!("Definition: pub const PI: f64 = 3.14159265358979323846264338327950288_f64;");
println!("Print it: {:.35}", f64::PI);
println!("Different after 16 significant digits ----------| ");
println!("##############################################################################");
println!("Question 1: Why do the digits differ after 16 significant digits when printed?");
println!("##############################################################################");

println!("PERFORM ASSERTIONS...");
assert_eq!(f64::PI, 3.14159265358979323846264338327950288_f64); // 36 significant digits definition
assert_eq!(f64::PI, 3.141592653589793_f64); // 16 significant digits (less then the 36 in definition)
// compares up to here -------------|
assert_eq!(f64::PI, 3.14159265358979300000000000000000000_f64); // 36 significant digits (16 used in equality comparison)
assert_ne!(f64::PI, 3.14159265358979_f64); // 15 significant digits (not equal)

println!("PERFORM EQUALITY CHECK...");
if 3.14159265358979323846264338327950288_f64 == 3.14159265358979300000000000000000000_f64 {
println!("BAD: floats considered equal even when they differ past 16 significant digits");
println!("######################################################################");
println!("Question 2: Why does equality checking use only 16 significant digits?");
println!("They are defined using 36 significant digits so why can't we perform");
println!("an equality check with this accuracy?");
println!("######################################################################");
} else {
println!("GOOD: floats considered different when they differ past 16 significant digits");
println!("NOTE: This block won't execute :(");
}
}

我知道浮点运算可能很棘手,但我想知道这种棘手是否也会影响 f64 的打印和执行相等性检查。这是上面代码的输出:

Checking f64 PI...
Definition: pub const PI: f64 = 3.14159265358979323846264338327950288_f64;
Print it: 3.14159265358979311599796346854418516
Different after 16 significant digits ----------|
##############################################################################
Question 1: Why do the digits differ after 16 significant digits when printed?
##############################################################################
PERFORM ASSERTIONS...
PERFORM EQUALITY CHECK...
BAD: floats considered equal even when they differ past 16 significant digits
######################################################################
Question 2: Why does equality checking use only 16 significant digits?
They are defined using 36 significant digits so why can't we perform
an equality check with this accuracy?
######################################################################

最佳答案

f64,顾名思义,以 64 位存储。在这个固定数量的存储空间中,我们只能对固定数量的数字进行编码(具体来说,其中 52 个位专用于有效位)。如果您在浮点文字中使用更多数字,则存储在 f64 变量中的数字将四舍五入为可用位数表示的最接近的数字。对于 f64 这意味着我们总是可以精确地表示 15 位十进制数字,有时是 16 位。这就解释了为什么有时即使您在源代码中使用不同的浮点字面量数字看起来相等:这是因为在四舍五入到最接近的可表示数字,它们是相同的。

打印不同数字的原因是一样的。该数字在存储时四舍五入到最接近的可表示数字,并在打印时再次转换回十进制。额外的数字来自二进制到十进制的转换,但小数点后 15 或 16 位之后的数字大多没有意义——它们不携带任何关于所表示数字的额外信息。

请注意,这些都不是 Rust 特有的。大多数现代编程语言使用 IEEE 754-1985 标准来表示 float ,因此它们的行为相同。如果你想要任意精度的算术,你通常需要使用一些库,例如rug crate .

关于rust - 为什么 Rust 只使用 16 位有效数字进行 f64 相等检查?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65719216/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com