gpt4 book ai didi

rust - 如何将 f64 转换为 f32 并获得最接近的近似值和下一个更大或更小的值?

转载 作者:行者123 更新时间:2023-11-29 07:48:30 33 4
gpt4 key购买 nike

该操作可能的伪代码可能是:

fn f32_greater(x: f64) -> f32 {
let mut y = x as f32; //I get closest
while f64::from(y) < x {
y = nextafter(y, f32::INFINITY);
}
y
}

fn f32_smaller(x: f64) -> f32 {
let mut y = x as f32; //I get closest
while f64::from(y) > x {
y = nextafter(y, f32::NEG_INFINITY);
}
y
}

我找不到与 C11 的 nextafter 等效的项在 libc crate 或 the methods on f64 中运行

对于上下文,我有一个使用 f32 的 R 树索引。我想搜索坐标为 f64 的区域,因此我需要 f32 中包含 f64 值的最小可能区域。

最佳答案

这个函数是 removed from the standard library .一种解决方案是使用 the float_extras crate ,但我真的不喜欢这个 crate 的方式,所以这里是我的解决方案:

mod float {
use libc::{c_double, c_float};
use std::{f32, f64};

#[link_name = "m"]
extern "C" {
pub fn nextafter(x: c_double, y: c_double) -> c_double;
pub fn nextafterf(x: c_float, y: c_float) -> c_float;
// long double nextafterl(long double x, long double y);

// double nexttoward(double x, long double y);
// float nexttowardf(float x, long double y);
// long double nexttowardl(long double x, long double y);
}

pub trait NextAfter {
fn next_after(self, y: Self) -> Self;
}

impl NextAfter for f32 {
fn next_after(self, y: Self) -> Self {
unsafe { nextafterf(self, y) }
}
}

impl NextAfter for f64 {
fn next_after(self, y: Self) -> Self {
unsafe { nextafter(self, y) }
}
}

pub trait Succ {
fn succ(self) -> Self;
}

impl Succ for f32 {
fn succ(self) -> Self {
self.next_after(f32::INFINITY)
}
}

impl Succ for f64 {
fn succ(self) -> Self {
self.next_after(f64::INFINITY)
}
}

pub trait Pred {
fn pred(self) -> Self;
}
impl Pred for f32 {
fn pred(self) -> Self {
self.next_after(f32::NEG_INFINITY)
}
}

impl Pred for f64 {
fn pred(self) -> Self {
self.next_after(f64::NEG_INFINITY)
}
}

}

use crate::float::{Pred, Succ};
use num_traits::cast::{FromPrimitive, ToPrimitive};

fn f32_greater<T>(x: T) -> Option<f32>
where
T: ToPrimitive + FromPrimitive + std::cmp::PartialOrd,
{
let mut y = x.to_f32()?;
while T::from_f32(y)? < x {
y = y.succ();
}
Some(y)
}

fn f32_smaller<T>(x: T) -> Option<f32>
where
T: ToPrimitive + FromPrimitive + std::cmp::PartialOrd,
{
let mut y = x.to_f32()?;
while T::from_f32(y)? > x {
y = y.pred();
}
Some(y)
}

fn main() {
let a = 42.4242424242424242;
println!(
"{:.16?} < {:.16} < {:.16?}",
f32_smaller(a),
a,
f32_greater(a)
);
}

我不明白他们为什么要don't include it in the num crate .

关于rust - 如何将 f64 转换为 f32 并获得最接近的近似值和下一个更大或更小的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56348835/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com