如何以任意精度水平进行比较,以便我可以看到两个数字相同?在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()的东西,但它与pythons版本不同,它似乎采用零参数。
答案 0 :(得分:7)
来自Python文档:
注意
round()
对浮点数的行为可能会令人惊讶:例如,round(2.675, 2)
提供2.67
而不是预期的2.68
。这不是一个错误:这是因为大多数小数部分不能完全表示为浮点数。
有关详细信息,请查看What Every Programmer Should Know About Floating-Point Arithmetic。
如果您不了解计算机如何处理浮点数,请不要使用此代码。如果你知道自己遇到了什么麻烦:
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)
)一种可能的替代方案是使用定点或任意精度类型,其中任何一种都会变得更慢但在逻辑上与大多数人保持一致。
答案 1 :(得分:0)
这个似乎对我来说很好。
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;
}
}