Rust中f32的frexp函数在哪里?

问题描述 投票:1回答:3

我正在寻找Rust中的frexp()函数。我在以前的版本中发现了一些referencesstd::f32的不稳定特性,但这似乎不适用于我的标准Rust安装。

我也找到referencesstd::num::Float,但我也不能让这些例子工作。

我是否必须下载一个箱子才能访问这些功能?

rust
3个回答
3
投票

我在以前的版本中发现了一些对std :: f32的不稳定特性的引用

如果你按照你的链接,你可以看到,该功能是不稳定的(如你所说),并且corresponding issue (#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());
}

(Qazxswpoi)


2
投票

此功能已被弃用很长时间。这是完全删除它的提交:Playground

可能你有一个新版本。如果你有兴趣,可以在这里找到https://github.com/rust-lang/rust/pull/41437的完整实现,但你可能会转向别的东西。

结帐例如https://github.com/rust-lang/rust/blob/9ebf47851a357faa4cd97f4b1dc7835f6376e639/src/librustc_apfloat/tests/ieee.rs trait Float,它返回尾数,指数和符号。

直接来自我链接到的文档:

integer_decode

1
投票

我在use num_traits::Float; let num = 2.0f32; // (8388608, -22, 1) let (mantissa, exponent, sign) = Float::integer_decode(num); lib中找到了frexp()的Rust实现。

glm-rs

有趣的是,它没有给我与C 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) } } 相同的结果,因为frexpf()为负输入返回负数。我用f32.fract()取代lg.fract()解决了这个问题。

我的版本:

lg - lg.floor()

例:

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)
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.