[英]Why can I not use the MAX and MIN values of f32 and f64 in a call to rand::rngs::ThreadRng::gen_range() in Rust
我有一個我編寫的實用程序來生成虛擬數據。 例如,你可以寫:
giveme 12000 u32
... 獲取 12000 個 32 位無符號整數的數組。
可以設置最大和/或最小允許值,因此您可以編寫:
giveme 100 f32 --max=155.25
如果一個或另一個沒有給出,程序使用type::MAX
和type::MIN
。
但是,對於浮點類型,無法將這些值傳遞給rand::rngs::ThreadRng::gen_range()
。
這是我的 f64 代碼:
fn generate_gift(gift_type: & GiftType,
generator: &mut rand::rngs::ThreadRng,
min: Option<f64>,
max: Option<f64>) -> Gift
{
match gift_type
{
...
GiftType::Float64 =>
{
let _min: f64 = min.unwrap_or(f64::MIN);
let _max: f64 = max.unwrap_or(f64::MAX);
let x: f64 = generator.gen_range(_min..=_max);
Gift::Float64(x)
},
}
}
如果浮點、32 位或 64 位缺少一個或兩個限制,則會出現此錯誤:
thread 'main' panicked at 'UniformSampler::sample_single: range overflow', /home/jack/.cargo/registry/src/github.com-1ecc6299db9ec823/rand-0.8.5/src/distributions/uniform.rs:998:1
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
為什么會出現這個錯誤對我來說並不明顯。 你能解釋一下嗎?
這是用於生成浮點數的限制,請參見#1090 。
gen_range(f64::MIN..f64::MAX) 導致高 - 低溢出
f64:我們將其視為實數的近似值,並且按照慣例,限制在 0 到 1 的范圍內(如果沒有另外指定)。 我們將回到稍后使用的轉換; 現在請注意,這些會產生 52-53 位的精度(取決於使用哪種轉換,output 將以 ε 或 ε/2 為步長,其中 1+ε 是大於 1 的最小可表示值)。
對於 f32 和 f64,使用范圍 0.0.. 1.0(不包括 1.0),原因有兩個:(a)這是隨機數生成器的常見做法,以及(b)因為對於許多目的,樣本分布均勻(沿實數行)很重要,這只有通過限制范圍才可能用於浮點表示。
它是rand
的限制。
在源代碼中它計算high - low
在您的情況下是inf
,實現會檢查這個並引發這個錯誤。
https://docs.rs/rand/0.8.5/src/rand/distributions/uniform.rs.html#811-814
該算法首先計算[1,2)
中的一個隨機數,然后根據區間的長度對其進行縮放。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.