1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#[macro_export]
macro_rules! approx_eq {
($typ:ty, $lhs:expr, $rhs:expr) => {
{
let m: <$typ as $crate::ApproxEq>::Margin = Default::default();
<$typ as $crate::ApproxEq>::approx_eq($lhs, $rhs, m)
}
};
($typ:ty, $lhs:expr, $rhs:expr $(, $set:ident = $val:expr)*) => {
{
let m = <$typ as $crate::ApproxEq>::Margin::zero()$(.$set($val))*;
<$typ as $crate::ApproxEq>::approx_eq($lhs, $rhs, m)
}
};
($typ:ty, $lhs:expr, $rhs:expr, $marg:expr) => {
{
<$typ as $crate::ApproxEq>::approx_eq($lhs, $rhs, $marg)
}
};
}
macro_rules! saturating_abs_i32 {
($val:expr) => {
if $val.is_negative() {
match $val.checked_neg() {
Some(v) => v,
None => core::i32::MAX
}
} else {
$val
}
};
}
macro_rules! saturating_abs_i64 {
($val:expr) => {
if $val.is_negative() {
match $val.checked_neg() {
Some(v) => v,
None => core::i64::MAX
}
} else {
$val
}
};
}
#[test]
fn test_macro() {
let a: f32 = 0.15 + 0.15 + 0.15;
let b: f32 = 0.1 + 0.1 + 0.25;
assert!( approx_eq!(f32, a, b) );
assert!( approx_eq!(f32, a, b, ulps = 2) );
assert!( approx_eq!(f32, a, b, epsilon = 0.00000003) );
assert!( approx_eq!(f32, a, b, epsilon = 0.00000003, ulps = 2) );
assert!( approx_eq!(f32, a, b, (0.0, 2)) );
}
#[test]
fn test_macro_2() {
assert!( approx_eq!(f64, 1000000_f64, 1000000.0000000003_f64) );
assert!( approx_eq!(f64, 1000000_f64, 1000000.0000000003_f64, ulps=3) );
assert!( approx_eq!(f64, 1000000_f64, 1000000.0000000003_f64, epsilon=0.0000000004) );
assert!( approx_eq!(f64, 1000000_f64, 1000000.0000000003_f64, (0.0000000004, 0)) );
assert!( approx_eq!(f64, 1000000_f64, 1000000.0000000003_f64, (0.0, 3)) );
}
#[test]
fn test_macro_3() {
use crate::F32Margin;
let a: f32 = 0.15 + 0.15 + 0.15;
let b: f32 = 0.1 + 0.1 + 0.25;
assert!( approx_eq!(f32, a, b, F32Margin { epsilon: 0.0, ulps: 2 }) );
assert!( approx_eq!(f32, a, b, F32Margin::default()) );
}