【发布时间】:2021-08-29 06:20:17
【问题描述】:
由于精度错误,使用浮点数 f64 时我的测试失败。
use std::ops::Sub;
#[derive(Debug, PartialEq, Clone, Copy)]
struct Audio {
amp: f64,
}
impl Sub for Audio {
type Output = Self;
fn sub(self, other: Self) -> Self::Output {
Self {
amp: self.amp - other.amp,
}
}
}
#[test]
fn subtract_audio() {
let audio1 = Audio { amp: 0.9 };
let audio2 = Audio { amp: 0.3 };
assert_eq!(audio1 - audio2, Audio { amp: 0.6 });
assert_ne!(audio1 - audio2, Audio { amp: 1.2 });
assert_ne!(audio1 - audio2, Audio { amp: 0.3 });
}
我收到以下错误:
---- subtract_audio stdout ----
thread 'subtract_audio' panicked at 'assertion failed: `(left == right)`
left: `Audio { amp: 0.6000000000000001 }`,
right: `Audio { amp: 0.6 }`', src/lib.rs:23:5
如何测试带有f64 之类的浮点数的结构?
【问题讨论】:
-
这能回答你的问题吗? Is floating point math broken?
-
您的问题不在于您的
Sub实现,而在于PartialEq的派生实现。最好手动实现,测试该值是否在您期望的公差范围内。 -
@eggyal 我了解浮点数,谢谢。你会说实施
PartialEq比我发布的答案更好吗?谢谢。 -
派生的
PartialEq实现对于包含浮点数的结构来说是毫无用处的,并且可能会导致意外且难以追踪的错误——所以我绝对建议删除它。如果由于其他原因该结构仍然需要实现PartialEq,那么无论如何您都需要手动执行...之后您的原始assert_eq将按预期工作。如果您没有任何其他理由实施PartialEq,那么我想这取决于您使用哪种方法,但我认为实施该特征可以更清楚地捕捉意图。 -
当然,如果您在比较过程中的容差取决于上下文,那么实现
PartialEq可能是个坏主意。
标签: testing struct rust floating-point precision