簡體   English   中英

檢查一個數字是否可以完全表示為`f32`

[英]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是顯而易見且最快的,但也有替代方案:例如f128BigDecimalrug rationalfloat ),然后檢查結果是否等於將其自身轉換為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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM