-
Notifications
You must be signed in to change notification settings - Fork 89
/
Copy pathbasic_math.rs
153 lines (132 loc) · 4.66 KB
/
basic_math.rs
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#![feature(test)]
#![no_std]
#![no_main]
#![test_runner(common::test_case_runner)]
#![feature(custom_test_frameworks)]
#![reexport_test_harness_main = "test_main"]
#[macro_use]
extern crate float_cmp;
use core::hint::black_box;
use common::exit;
mod common;
#[test_case]
fn add1() {
let x = black_box(1) + black_box(2);
assert_eq!(x, 3);
}
#[test_case]
fn subtest() {
int_test::<u8>();
int_test::<u16>();
int_test::<u32>();
int_test::<u64>();
int_test::<u128>();
int_test::<i8>();
int_test::<i16>();
int_test::<i32>();
int_test::<i64>();
int_test::<i128>();
sint_test::<i8>();
sint_test::<i16>();
sint_test::<i32>();
sint_test::<i64>();
sint_test::<i128>();
}
fn int_test<T>()
where
T: core::fmt::Debug,
T: num_traits::int::PrimInt,
{
let fifteen = T::from(15).unwrap();
let ten = T::from(10).unwrap();
let r_five: T = black_box(fifteen) - black_box(ten);
let r_zero: T = black_box(fifteen) - black_box(fifteen);
assert_eq!(r_five, T::from(5).unwrap());
assert_eq!(r_zero, T::from(0).unwrap());
let r_twentyfive: T = black_box(fifteen) + black_box(ten);
let r_twentyfive2: T = black_box(r_zero) + black_box(r_twentyfive);
assert_eq!(r_twentyfive, T::from(25).unwrap());
assert_eq!(r_twentyfive2, r_twentyfive);
let r_hundred: T = black_box(ten) * black_box(ten);
let r_hundred2: T = black_box(ten).pow(2);
let r_zero: T = black_box(r_hundred) * black_box(r_zero);
assert_eq!(r_hundred, T::from(100).unwrap());
assert_eq!(r_hundred, r_hundred2);
assert_eq!(r_zero, T::from(0).unwrap());
let r_ten: T = black_box(r_hundred) / black_box(ten);
let r_one: T = black_box(r_ten) / black_box(ten);
let r_zero: T = black_box(r_one) / black_box(ten);
assert_eq!(r_ten, ten);
assert_eq!(r_one, T::from(1).unwrap());
assert_eq!(r_zero, T::from(0).unwrap());
}
fn sint_test<T>()
where
T: core::fmt::Debug,
T: num_traits::sign::Signed,
T: num_traits::int::PrimInt,
{
let fifteen = T::from(15).unwrap();
let ten = T::from(10).unwrap();
let r_minusfive: T = black_box(ten) - black_box(fifteen);
assert_eq!(r_minusfive, T::from(-5).unwrap());
let r_minusfifteen: T = black_box(r_minusfive) - black_box(ten);
assert_eq!(r_minusfifteen, T::from(-15).unwrap());
let r_fifteen: T = black_box(r_minusfifteen) + black_box(fifteen) + black_box(fifteen);
assert_eq!(r_fifteen, fifteen);
let r_minusseventyfive: T = black_box(r_minusfive) * black_box(fifteen);
let r_zero: T = black_box(r_minusseventyfive) * black_box(T::from(0).unwrap());
assert_eq!(r_minusseventyfive, T::from(-75).unwrap());
assert_eq!(r_zero, T::from(0).unwrap());
assert_eq!(r_zero, T::from(-0).unwrap());
let r_minusseven: T = black_box(r_minusseventyfive) / black_box(ten);
assert_eq!(r_minusseven, T::from(-7).unwrap());
let r_fortynine: T = black_box(r_minusseven).pow(2);
let r_fortynine2: T = black_box(r_minusseven) * black_box(r_minusseven);
assert_eq!(r_fortynine, T::from(49).unwrap());
assert_eq!(r_fortynine, r_fortynine2);
}
#[test_case]
fn test_f64_arithmetic() {
let x = black_box::<f64>(65.2);
let y = black_box::<f64>(89.123);
let z = x * y;
assert!(approx_eq!(f64, z, 5810.8196f64, ulps = 1));
let z = z * y;
assert!(approx_eq!(f64, z, 517_877.675_210_8f64, ulps = 1));
let z = z * y;
assert!(approx_eq!(f64, z, 46_154_812.047_812_13f64, ulps = 2));
let z = z * y;
assert!(approx_eq!(f64, z, 4_113_455_314.137_160_3f64, ulps = 3));
let z = black_box(z) / y;
assert!(approx_eq!(f64, z, 46_154_812.047_812_13f64, ulps = 2));
assert!(!approx_eq!(f64, z, 46_154_812.047_812_13f64, ulps = 1)); // If we haven't lost any precision, the something is fishy
let z = black_box(z) / y;
assert!(approx_eq!(f64, z, 517_877.675_210_8f64, ulps = 2));
assert!(!approx_eq!(f64, z, 517_877.675_210_8f64, ulps = 1));
// Division
let x = black_box::<f64>(4.0);
let y = black_box::<f64>(5.0);
let z = x / y;
assert!(approx_eq!(f64, z, 0.8f64, ulps = 0));
let z = black_box(z) / y;
assert!(approx_eq!(f64, z, 0.16f64, ulps = 0));
// 0100011110101110000101000111101011100001010001111011 exp 01111111100
let z = black_box(z) / y;
assert!(approx_eq!(f64, z, 0.032f64, ulps = 0));
let z = black_box(z) / y;
assert!(approx_eq!(f64, z, 0.0064f64, ulps = 0));
//1010001101101110001011101011000111000100001100101101 exp 01111110111
let z = black_box(z) / y;
assert!(approx_eq!(f64, z, 0.00128f64, ulps = 0));
//0b0011111101010100111110001011010110001000111000110110100011110001
let z = black_box(z) * black_box(y) * black_box(y) * black_box(y);
assert!(approx_eq!(f64, z, 0.16f64, ulps = 0));
let z = black_box(z * y);
assert!(approx_eq!(f64, z, 0.8f64, ulps = 0));
}
#[unsafe(no_mangle)]
extern "C" fn runtime_entry(_argc: i32, _argv: *const *const u8, _env: *const *const u8) -> ! {
test_main();
exit(false);
}