[英]Check if a number is exactly representable as `f32`
我想知道值是1/256,2 / 256,3 / 256,...... 254/256和255/256是否完全可以表示為f32
。 現在,聰明的人會考慮浮點數如何工作並找出那種方式。 但我想在一個程序中檢查一下。 我要檢查的所有數字都是分數,我控制值(即沒有用戶輸入)。
我從這開始:
for n in 1u8..=255 {
let f = (n as f32) / 256.0;
println!("{}", f);
}
但現在呢? 我嘗試打印數字,看是否有大量的重復數字,但這並不總是有效。 例如,0.4不完全可表示:
println!("{}", 0.4); // prints "0.4"
println!("{:.20}", 0.4); // prints "0.40000000000000002220"
在這里,我們必須手動提高精度以查看問題。 無論如何,無論如何,查看字符串輸出似乎是次優解決方案。
首先我認為f32
上可能有一個方法,但這沒有多大意義,是嗎? 因為當f32
已經存在時,無法知道它的值是否有意。 因此,我們必須找出何時創建浮點值並與“理想化”值進行比較?
有沒有辦法檢查一個值是否可以精確表示為f32
?
來自rug
crate的 Rational
類型可以精確地表示分數。 它還實現了PartialEq<f32>
因此您可以直接將精確表示與f32
進行比較,以檢查它們是否相等。
for n in 1u8..=255u8 {
let rat = Rational::from((n, 256));
let f = (n as f32) / 256.0;
println!("{}/256 -> {}", n, rat == f);
}
正如您從輸出中看到的那樣,您要測試的數字確實可以完全表示為f32
。
要獲得更有趣的輸出,請嘗試1 / n
:
for n in 1u8..=255u8 {
let rat = Rational::from((1, n));
let f = 1.0 / (n as f32);
println!("1/{} -> {}", n, rat == f);
}
這表明只有具有2次冪分母的分數才能准確表示。
以更高的精度進行您想要的計算( f64
是顯而易見且最快的,但也有替代方案:例如f128
, BigDecimal
, rug
的 rational
或float
等 ),然后檢查結果是否等於將其自身轉換為f32
然后回來。
假設f64
為例
d.is_finite() && (d as f32) as f64 == d
當然,正如Jojonete的評論指出的那樣,這些計算的結果可能最終可以完全表示為f32
即使確切的結果不是這樣。 所以你想要的數據類型將取決於計算。 例如
1 / 256,2 / 256,3 / 256,...... 254/256和255/256
rug::rational
當然是准確的( f64
,但是你需要“考慮浮點數如何工作並找出那種方式”至少一點)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.