簡體   English   中英

Rust中f32的frexp函數在哪里?

[英]Where is the frexp function for f32 in Rust?

我正在尋找frexp()中的frexp()函數,在以前的發行版中發現了 std::f32不穩定功能的一些引用 ,但這似乎不適用於我的標准Rust安裝。

我還找到了對std::num::Float 引用 ,但是我也無法使示例正常工作。

我必須下載一個板條箱才能使用這些功能嗎?

我在以前的版本中發現了一些有關std :: f32不穩定功能的引用

如果您單擊鏈接,您會看到該功能不穩定(如您所說),並且相應的問題(#27752)已關閉。 因此,該功能部件不再可用(在PR#41437中刪除)。

我還找到了對std::num::Float引用

如果您查看該URL,您會注意到,這是2015年的文檔,因此也已棄用。


不幸的是,我找不到任何可以為您提供Rust實現的板條箱,但是由於Rust具有完整的FFI支持,因此您可以調用相應的c函數。

use std::os::raw::{c_float, c_double, c_int};

extern "C" {
    fn frexp(x: c_double, exp: *mut c_int) -> c_double;
    fn frexpf(x: c_float, exp: *mut c_int) -> c_float;
}

pub trait FloatExp: Sized {
    fn frexp(self) -> (Self, i32);
}

impl FloatExp for f64 {
    fn frexp(self) -> (Self, i32) {
        let mut exp: c_int = 0;
        let res = unsafe { frexp(self, &mut exp) };
        (res, exp)
    }
}

impl FloatExp for f32 {
    fn frexp(self) -> (Self, i32) {
        let mut exp: c_int = 0;
        let res = unsafe { frexpf(self, &mut exp) };
        (res, exp)
    }
}

fn main() {
    println!("{:?}", (1.3f64).frexp());
    println!("{:?}", (0.3f32).frexp());
}

游樂場

此功能已被棄用很長時間了。 這是完全刪除它的提交: https : //github.com/rust-lang/rust/pull/41437

您可能有一個新版本。 如果您有興趣,可以在這里找到完整的實現https://github.com/rust-lang/rust/blob/9ebf47851a357faa4cd97f4b1dc7835f6376e639/src/librustc_apfloat/tests/ieee.rs ,但是您可能應該改用其他方法。

例如,檢出Float特性Float _ integer_decode ,它返回尾數,指數和符號。

直接來自我鏈接到的文檔:

use num_traits::Float;    
let num = 2.0f32;    
// (8388608, -22, 1)
let (mantissa, exponent, sign) = Float::integer_decode(num);

我在glm-rs lib中找到了frexp()的Rust實現。

fn frexp(self) -> ($t, isize) {
    // CHECK: use impl in `libstd` after it's stable.
    if self.is_zero() || self.is_infinite() || self.is_nan() {
        (self, 0)
    } else {
        let lg = self.abs().log2();
        let x = (lg.fract() - 1.).exp2();
        let exp = lg.floor() + 1.;
        (self.signum() * x, exp as isize)
    }
}

有趣的是,它沒有給我與C frexpf()相同的結果,因為f32.fract()對於負輸入返回負數。 我通過用lg - lg.floor()替換lg.fract()解決了它。

我的版本:

fn frexp(s : f32) -> (f32, i32) {
    if 0.0 == s {
        return (s, 0);
    } else {
        let lg = s.abs().log2();
        let x = (lg - lg.floor() - 1.0).exp2();
        let exp = lg.floor() + 1.0;
        (s.signum() * x, exp as i32)
    }
}

例:

let x = 0.3f32;
println!("{:?}", (x).frexp()); // (0.6, -1)
println!("{:?}", glmfrexp(x)); // (0.3, -1)
println!("{:?}", myfrexp(x));  // (0.6, -1)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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