1//! These tests are adapted from the Rust core library's unittests. 2 3#![cfg(not(feature = "compact"))] 4 5use minimal_lexical::lemire; 6use minimal_lexical::num::Float; 7 8fn compute_error32(q: i32, w: u64) -> (i32, u64) { 9 let fp = lemire::compute_error::<f32>(q, w); 10 (fp.exp, fp.mant) 11} 12 13fn compute_error64(q: i32, w: u64) -> (i32, u64) { 14 let fp = lemire::compute_error::<f64>(q, w); 15 (fp.exp, fp.mant) 16} 17 18fn compute_error_scaled32(q: i32, w: u64, lz: i32) -> (i32, u64) { 19 let fp = lemire::compute_error_scaled::<f32>(q, w, lz); 20 (fp.exp, fp.mant) 21} 22 23fn compute_error_scaled64(q: i32, w: u64, lz: i32) -> (i32, u64) { 24 let fp = lemire::compute_error_scaled::<f64>(q, w, lz); 25 (fp.exp, fp.mant) 26} 27 28fn compute_float32(q: i32, w: u64) -> (i32, u64) { 29 let fp = lemire::compute_float::<f32>(q, w); 30 (fp.exp, fp.mant) 31} 32 33fn compute_float64(q: i32, w: u64) -> (i32, u64) { 34 let fp = lemire::compute_float::<f64>(q, w); 35 (fp.exp, fp.mant) 36} 37 38#[test] 39fn compute_error32_test() { 40 // These test near-halfway cases for single-precision floats. 41 assert_eq!(compute_error32(0, 16777216), (111 + f32::INVALID_FP, 9223372036854775808)); 42 assert_eq!(compute_error32(0, 16777217), (111 + f32::INVALID_FP, 9223372586610589696)); 43 assert_eq!(compute_error32(0, 16777218), (111 + f32::INVALID_FP, 9223373136366403584)); 44 assert_eq!(compute_error32(0, 16777219), (111 + f32::INVALID_FP, 9223373686122217472)); 45 assert_eq!(compute_error32(0, 16777220), (111 + f32::INVALID_FP, 9223374235878031360)); 46 47 // These are examples of the above tests, with 48 // digits from the exponent shifted to the mantissa. 49 assert_eq!( 50 compute_error32(-10, 167772160000000000), 51 (111 + f32::INVALID_FP, 9223372036854775808) 52 ); 53 assert_eq!( 54 compute_error32(-10, 167772170000000000), 55 (111 + f32::INVALID_FP, 9223372586610589696) 56 ); 57 assert_eq!( 58 compute_error32(-10, 167772180000000000), 59 (111 + f32::INVALID_FP, 9223373136366403584) 60 ); 61 // Let's check the lines to see if anything is different in table... 62 assert_eq!( 63 compute_error32(-10, 167772190000000000), 64 (111 + f32::INVALID_FP, 9223373686122217472) 65 ); 66 assert_eq!( 67 compute_error32(-10, 167772200000000000), 68 (111 + f32::INVALID_FP, 9223374235878031360) 69 ); 70} 71 72#[test] 73fn compute_error64_test() { 74 // These test near-halfway cases for double-precision floats. 75 assert_eq!(compute_error64(0, 9007199254740992), (1065 + f64::INVALID_FP, 9223372036854775808)); 76 assert_eq!(compute_error64(0, 9007199254740993), (1065 + f64::INVALID_FP, 9223372036854776832)); 77 assert_eq!(compute_error64(0, 9007199254740994), (1065 + f64::INVALID_FP, 9223372036854777856)); 78 assert_eq!(compute_error64(0, 9007199254740995), (1065 + f64::INVALID_FP, 9223372036854778880)); 79 assert_eq!(compute_error64(0, 9007199254740996), (1065 + f64::INVALID_FP, 9223372036854779904)); 80 assert_eq!( 81 compute_error64(0, 18014398509481984), 82 (1066 + f64::INVALID_FP, 9223372036854775808) 83 ); 84 assert_eq!( 85 compute_error64(0, 18014398509481986), 86 (1066 + f64::INVALID_FP, 9223372036854776832) 87 ); 88 assert_eq!( 89 compute_error64(0, 18014398509481988), 90 (1066 + f64::INVALID_FP, 9223372036854777856) 91 ); 92 assert_eq!( 93 compute_error64(0, 18014398509481990), 94 (1066 + f64::INVALID_FP, 9223372036854778880) 95 ); 96 assert_eq!( 97 compute_error64(0, 18014398509481992), 98 (1066 + f64::INVALID_FP, 9223372036854779904) 99 ); 100 101 // Test a much closer set of examples. 102 assert_eq!( 103 compute_error64(0, 9007199254740991), 104 (1064 + f64::INVALID_FP, 18446744073709549568) 105 ); 106 assert_eq!( 107 compute_error64(0, 9223372036854776831), 108 (1075 + f64::INVALID_FP, 9223372036854776830) 109 ); 110 assert_eq!( 111 compute_error64(0, 9223372036854776832), 112 (1075 + f64::INVALID_FP, 9223372036854776832) 113 ); 114 assert_eq!( 115 compute_error64(0, 9223372036854776833), 116 (1075 + f64::INVALID_FP, 9223372036854776832) 117 ); 118 assert_eq!( 119 compute_error64(-42, 9123456727292927), 120 (925 + f64::INVALID_FP, 13021432563531497894) 121 ); 122 assert_eq!( 123 compute_error64(-43, 91234567272929275), 124 (925 + f64::INVALID_FP, 13021432563531498606) 125 ); 126 assert_eq!( 127 compute_error64(-42, 9123456727292928), 128 (925 + f64::INVALID_FP, 13021432563531499320) 129 ); 130 131 // These are examples of the above tests, with 132 // digits from the exponent shifted to the mantissa. 133 assert_eq!( 134 compute_error64(-3, 9007199254740992000), 135 (1065 + f64::INVALID_FP, 9223372036854775808) 136 ); 137 assert_eq!( 138 compute_error64(-3, 9007199254740993000), 139 (1065 + f64::INVALID_FP, 9223372036854776832) 140 ); 141 assert_eq!( 142 compute_error64(-3, 9007199254740994000), 143 (1065 + f64::INVALID_FP, 9223372036854777856) 144 ); 145 assert_eq!( 146 compute_error64(-3, 9007199254740995000), 147 (1065 + f64::INVALID_FP, 9223372036854778880) 148 ); 149 assert_eq!( 150 compute_error64(-3, 9007199254740996000), 151 (1065 + f64::INVALID_FP, 9223372036854779904) 152 ); 153 154 // Test from errors in atof. 155 assert_eq!( 156 compute_error64(-18, 1000000178813934326), 157 (1012 + f64::INVALID_FP, 9223373686122217470) 158 ); 159 160 // Check edge-cases from previous errors. 161 assert_eq!( 162 compute_error64(-342, 2470328229206232720), 163 (-64 + f64::INVALID_FP, 18446744073709551608) 164 ); 165} 166 167#[test] 168fn compute_error_scaled32_test() { 169 // These are the same examples above, just using pre-computed scaled values. 170 171 // These test near-halfway cases for single-precision floats. 172 assert_eq!( 173 compute_error_scaled32(0, 4611686018427387904, 39), 174 (111 + f32::INVALID_FP, 9223372036854775808) 175 ); 176 assert_eq!( 177 compute_error_scaled32(0, 4611686293305294848, 39), 178 (111 + f32::INVALID_FP, 9223372586610589696) 179 ); 180 assert_eq!( 181 compute_error_scaled32(0, 4611686568183201792, 39), 182 (111 + f32::INVALID_FP, 9223373136366403584) 183 ); 184 assert_eq!( 185 compute_error_scaled32(0, 4611686843061108736, 39), 186 (111 + f32::INVALID_FP, 9223373686122217472) 187 ); 188 assert_eq!( 189 compute_error_scaled32(0, 4611687117939015680, 39), 190 (111 + f32::INVALID_FP, 9223374235878031360) 191 ); 192 193 assert_eq!( 194 compute_error_scaled32(-10, 9223372036854775808, 6), 195 (111 + f32::INVALID_FP, 9223372036854775808) 196 ); 197 assert_eq!( 198 compute_error_scaled32(-10, 9223372586610589696, 6), 199 (111 + f32::INVALID_FP, 9223372586610589696) 200 ); 201 assert_eq!( 202 compute_error_scaled32(-10, 9223373136366403584, 6), 203 (111 + f32::INVALID_FP, 9223373136366403584) 204 ); 205 assert_eq!( 206 compute_error_scaled32(-10, 9223373686122217472, 6), 207 (111 + f32::INVALID_FP, 9223373686122217472) 208 ); 209 assert_eq!( 210 compute_error_scaled32(-10, 9223374235878031360, 6), 211 (111 + f32::INVALID_FP, 9223374235878031360) 212 ); 213} 214 215#[test] 216fn compute_error_scaled64_test() { 217 // These are the same examples above, just using pre-computed scaled values. 218 219 // These test near-halfway cases for double-precision floats. 220 assert_eq!( 221 compute_error_scaled64(0, 4611686018427387904, 10), 222 (1065 + f64::INVALID_FP, 9223372036854775808) 223 ); 224 assert_eq!( 225 compute_error_scaled64(0, 4611686018427388416, 10), 226 (1065 + f64::INVALID_FP, 9223372036854776832) 227 ); 228 assert_eq!( 229 compute_error_scaled64(0, 4611686018427388928, 10), 230 (1065 + f64::INVALID_FP, 9223372036854777856) 231 ); 232 assert_eq!( 233 compute_error_scaled64(0, 4611686018427389440, 10), 234 (1065 + f64::INVALID_FP, 9223372036854778880) 235 ); 236 assert_eq!( 237 compute_error_scaled64(0, 4611686018427389952, 10), 238 (1065 + f64::INVALID_FP, 9223372036854779904) 239 ); 240 assert_eq!( 241 compute_error_scaled64(0, 4611686018427387904, 9), 242 (1066 + f64::INVALID_FP, 9223372036854775808) 243 ); 244 assert_eq!( 245 compute_error_scaled64(0, 4611686018427388416, 9), 246 (1066 + f64::INVALID_FP, 9223372036854776832) 247 ); 248 assert_eq!( 249 compute_error_scaled64(0, 4611686018427388928, 9), 250 (1066 + f64::INVALID_FP, 9223372036854777856) 251 ); 252 assert_eq!( 253 compute_error_scaled64(0, 4611686018427389440, 9), 254 (1066 + f64::INVALID_FP, 9223372036854778880) 255 ); 256 assert_eq!( 257 compute_error_scaled64(0, 4611686018427389952, 9), 258 (1066 + f64::INVALID_FP, 9223372036854779904) 259 ); 260 261 // Test a much closer set of examples. 262 assert_eq!( 263 compute_error_scaled64(0, 9223372036854774784, 11), 264 (1064 + f64::INVALID_FP, 18446744073709549568) 265 ); 266 assert_eq!( 267 compute_error_scaled64(0, 4611686018427388415, 0), 268 (1075 + f64::INVALID_FP, 9223372036854776830) 269 ); 270 assert_eq!( 271 compute_error_scaled64(0, 4611686018427388416, 0), 272 (1075 + f64::INVALID_FP, 9223372036854776832) 273 ); 274 assert_eq!( 275 compute_error_scaled64(0, 4611686018427388416, 0), 276 (1075 + f64::INVALID_FP, 9223372036854776832) 277 ); 278 assert_eq!( 279 compute_error_scaled64(-42, 6510716281765748947, 10), 280 (925 + f64::INVALID_FP, 13021432563531497894) 281 ); 282 assert_eq!( 283 compute_error_scaled64(-43, 6510716281765749303, 7), 284 (925 + f64::INVALID_FP, 13021432563531498606) 285 ); 286 assert_eq!( 287 compute_error_scaled64(-42, 6510716281765749660, 10), 288 (925 + f64::INVALID_FP, 13021432563531499320) 289 ); 290 291 // These are examples of the above tests, with 292 // digits from the exponent shifted to the mantissa. 293 assert_eq!( 294 compute_error_scaled64(-3, 9223372036854775808, 1), 295 (1065 + f64::INVALID_FP, 9223372036854775808) 296 ); 297 assert_eq!( 298 compute_error_scaled64(-3, 9223372036854776832, 1), 299 (1065 + f64::INVALID_FP, 9223372036854776832) 300 ); 301 assert_eq!( 302 compute_error_scaled64(-3, 9223372036854777856, 1), 303 (1065 + f64::INVALID_FP, 9223372036854777856) 304 ); 305 assert_eq!( 306 compute_error_scaled64(-3, 9223372036854778880, 1), 307 (1065 + f64::INVALID_FP, 9223372036854778880) 308 ); 309 assert_eq!( 310 compute_error_scaled64(-3, 9223372036854779904, 1), 311 (1065 + f64::INVALID_FP, 9223372036854779904) 312 ); 313 314 // Test from errors in atof. 315 assert_eq!( 316 compute_error_scaled64(-18, 9223373686122217470, 4), 317 (1012 + f64::INVALID_FP, 9223373686122217470) 318 ); 319 320 // Check edge-cases from previous errors. 321 assert_eq!( 322 compute_error_scaled64(-342, 9223372036854775804, 2), 323 (-64 + f64::INVALID_FP, 18446744073709551608) 324 ); 325} 326 327#[test] 328fn compute_float_f32_rounding() { 329 // These test near-halfway cases for single-precision floats. 330 assert_eq!(compute_float32(0, 16777216), (151, 0)); 331 assert_eq!(compute_float32(0, 16777217), (151, 0)); 332 assert_eq!(compute_float32(0, 16777218), (151, 1)); 333 assert_eq!(compute_float32(0, 16777219), (151, 2)); 334 assert_eq!(compute_float32(0, 16777220), (151, 2)); 335 336 // These are examples of the above tests, with 337 // digits from the exponent shifted to the mantissa. 338 assert_eq!(compute_float32(-10, 167772160000000000), (151, 0)); 339 assert_eq!(compute_float32(-10, 167772170000000000), (151, 0)); 340 assert_eq!(compute_float32(-10, 167772180000000000), (151, 1)); 341 // Let's check the lines to see if anything is different in table... 342 assert_eq!(compute_float32(-10, 167772190000000000), (151, 2)); 343 assert_eq!(compute_float32(-10, 167772200000000000), (151, 2)); 344} 345 346#[test] 347fn compute_float_f64_rounding() { 348 // Also need to check halfway cases **inside** that exponent range. 349 350 // These test near-halfway cases for double-precision floats. 351 assert_eq!(compute_float64(0, 9007199254740992), (1076, 0)); 352 assert_eq!(compute_float64(0, 9007199254740993), (1076, 0)); 353 assert_eq!(compute_float64(0, 9007199254740994), (1076, 1)); 354 assert_eq!(compute_float64(0, 9007199254740995), (1076, 2)); 355 assert_eq!(compute_float64(0, 9007199254740996), (1076, 2)); 356 assert_eq!(compute_float64(0, 18014398509481984), (1077, 0)); 357 assert_eq!(compute_float64(0, 18014398509481986), (1077, 0)); 358 assert_eq!(compute_float64(0, 18014398509481988), (1077, 1)); 359 assert_eq!(compute_float64(0, 18014398509481990), (1077, 2)); 360 assert_eq!(compute_float64(0, 18014398509481992), (1077, 2)); 361 362 // Test a much closer set of examples. 363 assert_eq!(compute_float64(0, 9007199254740991), (1075, 4503599627370495)); 364 assert_eq!(compute_float64(0, 9223372036854776831), (1086, 0)); 365 assert_eq!(compute_float64(0, 9223372036854776832), (1086, 0)); 366 assert_eq!(compute_float64(0, 9223372036854776833), (1086, 1)); 367 assert_eq!(compute_float64(-42, 9123456727292927), (936, 1854521741541368)); 368 assert_eq!(compute_float64(-43, 91234567272929275), (936, 1854521741541369)); 369 assert_eq!(compute_float64(-42, 9123456727292928), (936, 1854521741541369)); 370 371 // These are examples of the above tests, with 372 // digits from the exponent shifted to the mantissa. 373 assert_eq!(compute_float64(-3, 9007199254740992000), (1076, 0)); 374 assert_eq!(compute_float64(-3, 9007199254740993000), (1076, 0)); 375 assert_eq!(compute_float64(-3, 9007199254740994000), (1076, 1)); 376 assert_eq!(compute_float64(-3, 9007199254740995000), (1076, 2)); 377 assert_eq!(compute_float64(-3, 9007199254740996000), (1076, 2)); 378} 379