繁体   English   中英

将 Rust 中的两个浮点数与任意精度水平进行比较

[英]Comparison of two floats in Rust to arbitrary level of precision

如何在任意精度级别进行比较,以便我可以看到两个数字相同? 在 Python 中,我会使用像round()这样的函数,所以我在 Rust 中寻找等价的东西。

例如我有:

let x = 1.45555454;
let y = 1.45556766;

在我的情况下,它们相似到小数点后 2 位。 因此,为了比较, xy将变为 1.46。 我可以格式化这些,但这肯定很慢,检查等效性的最佳 Rust 方法是什么,所以:

if x == y { // called when we match to 2 decimal places}

进一步阐明问题并提供一些背景信息。 这真的是为了美元和美分的准确性。 所以通常在python会使用round()函数来解决所有问题。 是的,我知道浮点表示的局限性。 有两个计算金额的函数,我以美元计算,需要将美分部分处理到最接近的一分钱。

询问社区的原因是我怀疑如果我自己动手,它可能会影响性能,这就是我使用 Rust 的原因,所以我在这里。 另外,我在 Rust 文档中看到了一种叫做round() 的东西,但与 python 版本不同,它似乎采用零参数。

来自 Python 文档:

注意round()对浮点数的行为可能令人惊讶:例如, round(2.675, 2)给出2.67而不是预期的2.68 这不是错误:这是大多数十进制分数不能完全表示为浮点数的结果。

有关更多信息,请查看每个程序员应该了解的关于浮点运算的知识


如果您不了解计算机如何处理浮点数,请不要使用此代码 如果您知道自己遇到了什么麻烦:

fn approx_equal(a: f64, b: f64, decimal_places: u8) -> bool {
    let factor = 10.0f64.powi(decimal_places as i32);
    let a = (a * factor).trunc();
    let b = (b * factor).trunc();
    a == b
}

fn main() {
    assert!( approx_equal(1.234, 1.235, 1));
    assert!( approx_equal(1.234, 1.235, 2));
    assert!(!approx_equal(1.234, 1.235, 3));
}

已知(或可能)被此代码破坏的事物的非详尽列表:

  • 足够大的浮点数和/或小数点数
  • 非规范化数字
  • NaN
  • 无穷大
  • 接近于零的值 ( approx_equal(0.09, -0.09, 1) )

一个潜在的替代方法是使用定点或任意精度类型,这两种类型都会变慢,但对大多数人来说在逻辑上更一致。

这个对我来说似乎很有效。

fn approx_equal (a:f64,b:f64,dp:u8) -> bool {
    let p:f64 = 10f64.powf(-(dp as f64));

    if (a-b).abs() < p {
        return true;
    } else {
        return false;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM