[英]Comparison of two floats in Rust to arbitrary level of precision
如何在任意精度级别进行比较,以便我可以看到两个数字相同? 在 Python 中,我会使用像round()
这样的函数,所以我在 Rust 中寻找等价的东西。
例如我有:
let x = 1.45555454;
let y = 1.45556766;
在我的情况下,它们相似到小数点后 2 位。 因此,为了比较, x
和y
将变为 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));
}
已知(或可能)被此代码破坏的事物的非详尽列表:
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.