1use nautilus_core::correctness::FAILED;
22
23#[unsafe(no_mangle)]
31#[allow(unsafe_code)]
32pub static HIGH_PRECISION_MODE: u8 = cfg!(feature = "high-precision") as u8;
33
34#[cfg(feature = "high-precision")]
39pub const FIXED_PRECISION: u8 = 16;
41
42#[cfg(not(feature = "high-precision"))]
43pub const FIXED_PRECISION: u8 = 9;
45
46#[cfg(feature = "high-precision")]
51pub const PRECISION_BYTES: i32 = 16;
53
54#[cfg(not(feature = "high-precision"))]
55pub const PRECISION_BYTES: i32 = 8;
57
58#[cfg(feature = "high-precision")]
63pub const FIXED_SIZE_BINARY: &str = "FixedSizeBinary(16)";
65
66#[cfg(not(feature = "high-precision"))]
67pub const FIXED_SIZE_BINARY: &str = "FixedSizeBinary(8)";
69
70#[cfg(feature = "high-precision")]
75pub const FIXED_SCALAR: f64 = 10_000_000_000_000_000.0;
77
78#[cfg(not(feature = "high-precision"))]
79pub const FIXED_SCALAR: f64 = 1_000_000_000.0;
81
82#[cfg(feature = "high-precision")]
87pub const PRECISION_DIFF_SCALAR: f64 = 10_000_000.0; #[cfg(not(feature = "high-precision"))]
91pub const PRECISION_DIFF_SCALAR: f64 = 1.0;
93
94pub const MAX_FLOAT_PRECISION: u8 = 16;
105
106pub fn check_fixed_precision(precision: u8) -> anyhow::Result<()> {
112 #[cfg(feature = "defi")]
113 if precision > crate::defi::WEI_PRECISION {
114 anyhow::bail!("`precision` exceeded maximum `WEI_PRECISION` (18), was {precision}")
115 }
116
117 #[cfg(not(feature = "defi"))]
118 if precision > FIXED_PRECISION {
119 anyhow::bail!(
120 "`precision` exceeded maximum `FIXED_PRECISION` ({FIXED_PRECISION}), was {precision}"
121 )
122 }
123
124 Ok(())
125}
126
127#[must_use]
140pub fn f64_to_fixed_i64(value: f64, precision: u8) -> i64 {
141 check_fixed_precision(precision).expect(FAILED);
142 let pow1 = 10_i64.pow(u32::from(precision));
143 let pow2 = 10_i64.pow(u32::from(FIXED_PRECISION - precision));
144 let rounded = (value * pow1 as f64).round() as i64;
145 rounded * pow2
146}
147
148pub fn f64_to_fixed_i128(value: f64, precision: u8) -> i128 {
154 check_fixed_precision(precision).expect(FAILED);
155 let pow1 = 10_i128.pow(u32::from(precision));
156 let pow2 = 10_i128.pow(u32::from(FIXED_PRECISION - precision));
157 let rounded = (value * pow1 as f64).round() as i128;
158 rounded * pow2
159}
160
161#[must_use]
167pub fn f64_to_fixed_u64(value: f64, precision: u8) -> u64 {
168 check_fixed_precision(precision).expect(FAILED);
169 let pow1 = 10_u64.pow(u32::from(precision));
170 let pow2 = 10_u64.pow(u32::from(FIXED_PRECISION - precision));
171 let rounded = (value * pow1 as f64).round() as u64;
172 rounded * pow2
173}
174
175#[must_use]
181pub fn f64_to_fixed_u128(value: f64, precision: u8) -> u128 {
182 check_fixed_precision(precision).expect(FAILED);
183 let pow1 = 10_u128.pow(u32::from(precision));
184 let pow2 = 10_u128.pow(u32::from(FIXED_PRECISION - precision));
185 let rounded = (value * pow1 as f64).round() as u128;
186 rounded * pow2
187}
188
189#[must_use]
191pub fn fixed_i64_to_f64(value: i64) -> f64 {
192 (value as f64) / FIXED_SCALAR
193}
194
195#[must_use]
197pub fn fixed_i128_to_f64(value: i128) -> f64 {
198 (value as f64) / FIXED_SCALAR
199}
200
201#[must_use]
203pub fn fixed_u64_to_f64(value: u64) -> f64 {
204 (value as f64) / FIXED_SCALAR
205}
206
207#[must_use]
209pub fn fixed_u128_to_f64(value: u128) -> f64 {
210 (value as f64) / FIXED_SCALAR
211}
212
213#[cfg(feature = "high-precision")]
217#[cfg(test)]
218mod tests {
219 use nautilus_core::approx_eq;
220 use rstest::rstest;
221
222 use super::*;
223
224 #[cfg(not(feature = "high-precision"))]
225 #[rstest]
226 fn test_precision_boundaries() {
227 assert!(check_fixed_precision(0).is_ok());
228 assert!(check_fixed_precision(FIXED_PRECISION).is_ok());
229 assert!(check_fixed_precision(FIXED_PRECISION + 1).is_err());
230 }
231
232 #[cfg(feature = "defi")]
233 #[rstest]
234 fn test_precision_boundaries() {
235 use crate::defi::WEI_PRECISION;
236
237 assert!(check_fixed_precision(0).is_ok());
238 assert!(check_fixed_precision(WEI_PRECISION).is_ok());
239 assert!(check_fixed_precision(WEI_PRECISION + 1).is_err());
240 }
241
242 #[rstest]
243 #[case(0.0)]
244 #[case(1.0)]
245 #[case(-1.0)]
246 fn test_basic_roundtrip(#[case] value: f64) {
247 for precision in 0..=FIXED_PRECISION {
248 let fixed = f64_to_fixed_i128(value, precision);
249 let result = fixed_i128_to_f64(fixed);
250 assert!(approx_eq!(f64, value, result, epsilon = 0.001, ulps = 16));
251 }
252 }
253
254 #[rstest]
255 #[case(1000000.0)]
256 #[case(-1000000.0)]
257 fn test_large_value_roundtrip(#[case] value: f64) {
258 for precision in 0..=FIXED_PRECISION {
259 let fixed = f64_to_fixed_i128(value, precision);
260 let result = fixed_i128_to_f64(fixed);
261 assert!(approx_eq!(f64, value, result, epsilon = 0.000_1));
262 }
263 }
264
265 #[rstest]
266 #[case(0, 123456.0)]
267 #[case(0, 123456.7)]
268 #[case(1, 123456.7)]
269 #[case(2, 123456.78)]
270 #[case(8, 123456.12345678)]
271 fn test_precision_specific_values_basic(#[case] precision: u8, #[case] value: f64) {
272 let result = f64_to_fixed_i128(value, precision);
273 let back_converted = fixed_i128_to_f64(result);
274 let scale = 10.0_f64.powi(precision as i32);
276 let expected_rounded = (value * scale).round() / scale;
277 assert!((back_converted - expected_rounded).abs() < 1e-10);
278 }
279
280 #[rstest]
281 fn test_max_precision_values() {
282 let test_value = 123456.123456789;
284 let result = f64_to_fixed_i128(test_value, FIXED_PRECISION);
285 let back_converted = fixed_i128_to_f64(result);
286 assert!((back_converted - test_value).abs() < 1e-6);
288 }
289
290 #[rstest]
291 #[case(0.0)]
292 #[case(1.0)]
293 #[case(1000000.0)]
294 fn test_unsigned_basic_roundtrip(#[case] value: f64) {
295 for precision in 0..=FIXED_PRECISION {
296 let fixed = f64_to_fixed_u128(value, precision);
297 let result = fixed_u128_to_f64(fixed);
298 assert!(approx_eq!(f64, value, result, epsilon = 0.001, ulps = 16));
299 }
300 }
301
302 #[rstest]
303 #[case(0)]
304 #[case(FIXED_PRECISION)]
305 fn test_valid_precision(#[case] precision: u8) {
306 let result = check_fixed_precision(precision);
307 assert!(result.is_ok());
308 }
309
310 #[cfg(not(feature = "defi"))]
311 #[rstest]
312 fn test_invalid_precision() {
313 let precision = FIXED_PRECISION + 1;
314 let result = check_fixed_precision(precision);
315 assert!(result.is_err());
316 }
317
318 #[cfg(feature = "defi")]
319 #[rstest]
320 fn test_invalid_precision() {
321 use crate::defi::WEI_PRECISION;
322 let precision = WEI_PRECISION + 1;
323 let result = check_fixed_precision(precision);
324 assert!(result.is_err());
325 }
326
327 #[rstest]
328 #[case(0, 0.0)]
329 #[case(1, 1.0)]
330 #[case(1, 1.1)]
331 #[case(9, 0.000_000_001)]
332 #[case(16, 0.000_000_000_000_000_1)]
333 #[case(0, -0.0)]
334 #[case(1, -1.0)]
335 #[case(1, -1.1)]
336 #[case(9, -0.000_000_001)]
337 #[case(16, -0.000_000_000_000_000_1)]
338 fn test_f64_to_fixed_i128_to_fixed(#[case] precision: u8, #[case] value: f64) {
339 let fixed = f64_to_fixed_i128(value, precision);
340 let result = fixed_i128_to_f64(fixed);
341 assert_eq!(result, value);
342 }
343
344 #[rstest]
345 #[case(0, 0.0)]
346 #[case(1, 1.0)]
347 #[case(1, 1.1)]
348 #[case(9, 0.000_000_001)]
349 #[case(16, 0.000_000_000_000_000_1)]
350 fn test_f64_to_fixed_u128_to_fixed(#[case] precision: u8, #[case] value: f64) {
351 let fixed = f64_to_fixed_u128(value, precision);
352 let result = fixed_u128_to_f64(fixed);
353 assert_eq!(result, value);
354 }
355
356 #[rstest]
357 #[case(0, 123_456.0)]
358 #[case(0, 123_456.7)]
359 #[case(0, 123_456.4)]
360 #[case(1, 123_456.0)]
361 #[case(1, 123_456.7)]
362 #[case(1, 123_456.4)]
363 #[case(2, 123_456.0)]
364 #[case(2, 123_456.7)]
365 #[case(2, 123_456.4)]
366 fn test_f64_to_fixed_i128_with_precision(#[case] precision: u8, #[case] value: f64) {
367 let result = f64_to_fixed_i128(value, precision);
368
369 let pow1 = 10_i128.pow(u32::from(precision));
371 let pow2 = 10_i128.pow(u32::from(FIXED_PRECISION - precision));
372 let rounded = (value * pow1 as f64).round() as i128;
373 let expected = rounded * pow2;
374
375 assert_eq!(
376 result, expected,
377 "Failed for precision {precision}, value {value}: got {result}, expected {expected}"
378 );
379 }
380
381 #[rstest]
382 #[case(0, 5.555555555555555)]
383 #[case(1, 5.555555555555555)]
384 #[case(2, 5.555555555555555)]
385 #[case(3, 5.555555555555555)]
386 #[case(4, 5.555555555555555)]
387 #[case(5, 5.555555555555555)]
388 #[case(6, 5.555555555555555)]
389 #[case(7, 5.555555555555555)]
390 #[case(8, 5.555555555555555)]
391 #[case(9, 5.555555555555555)]
392 #[case(10, 5.555555555555555)]
393 #[case(11, 5.555555555555555)]
394 #[case(12, 5.555555555555555)]
395 #[case(13, 5.555555555555555)]
396 #[case(14, 5.555555555555555)]
397 #[case(15, 5.555555555555555)]
398 #[case(0, -5.555555555555555)]
399 #[case(1, -5.555555555555555)]
400 #[case(2, -5.555555555555555)]
401 #[case(3, -5.555555555555555)]
402 #[case(4, -5.555555555555555)]
403 #[case(5, -5.555555555555555)]
404 #[case(6, -5.555555555555555)]
405 #[case(7, -5.555555555555555)]
406 #[case(8, -5.555555555555555)]
407 #[case(9, -5.555555555555555)]
408 #[case(10, -5.555555555555555)]
409 #[case(11, -5.555555555555555)]
410 #[case(12, -5.555555555555555)]
411 #[case(13, -5.555555555555555)]
412 #[case(14, -5.555555555555555)]
413 #[case(15, -5.555555555555555)]
414 fn test_f64_to_fixed_i128(#[case] precision: u8, #[case] value: f64) {
415 if precision > FIXED_PRECISION {
417 return;
418 }
419
420 let result = f64_to_fixed_i128(value, precision);
421
422 let pow1 = 10_i128.pow(u32::from(precision));
424 let pow2 = 10_i128.pow(u32::from(FIXED_PRECISION - precision));
425 let rounded = (value * pow1 as f64).round() as i128;
426 let expected = rounded * pow2;
427
428 assert_eq!(
429 result, expected,
430 "Failed for precision {precision}, value {value}: got {result}, expected {expected}"
431 );
432 }
433
434 #[rstest]
435 #[case(0, 5.555555555555555)]
436 #[case(1, 5.555555555555555)]
437 #[case(2, 5.555555555555555)]
438 #[case(3, 5.555555555555555)]
439 #[case(4, 5.555555555555555)]
440 #[case(5, 5.555555555555555)]
441 #[case(6, 5.555555555555555)]
442 #[case(7, 5.555555555555555)]
443 #[case(8, 5.555555555555555)]
444 #[case(9, 5.555555555555555)]
445 #[case(10, 5.555555555555555)]
446 #[case(11, 5.555555555555555)]
447 #[case(12, 5.555555555555555)]
448 #[case(13, 5.555555555555555)]
449 #[case(14, 5.555555555555555)]
450 #[case(15, 5.555555555555555)]
451 #[case(16, 5.555555555555555)]
452 fn test_f64_to_fixed_u64(#[case] precision: u8, #[case] value: f64) {
453 if precision > FIXED_PRECISION {
455 return;
456 }
457
458 let result = f64_to_fixed_u128(value, precision);
459
460 let pow1 = 10_u128.pow(u32::from(precision));
462 let pow2 = 10_u128.pow(u32::from(FIXED_PRECISION - precision));
463 let rounded = (value * pow1 as f64).round() as u128;
464 let expected = rounded * pow2;
465
466 assert_eq!(
467 result, expected,
468 "Failed for precision {precision}, value {value}: got {result}, expected {expected}"
469 );
470 }
471
472 #[rstest]
473 fn test_fixed_i128_to_f64(
474 #[values(1, -1, 2, -2, 10, -10, 100, -100, 1_000, -1_000, -10_000, -100_000)] value: i128,
475 ) {
476 assert_eq!(fixed_i128_to_f64(value), value as f64 / FIXED_SCALAR);
477 }
478
479 #[rstest]
480 fn test_fixed_u128_to_f64(
481 #[values(
482 0,
483 1,
484 2,
485 3,
486 10,
487 100,
488 1_000,
489 10_000,
490 100_000,
491 1_000_000,
492 10_000_000,
493 100_000_000,
494 1_000_000_000,
495 10_000_000_000,
496 100_000_000_000,
497 1_000_000_000_000,
498 10_000_000_000_000,
499 100_000_000_000_000,
500 1_000_000_000_000_000,
501 10_000_000_000_000_000,
502 100_000_000_000_000_000,
503 1_000_000_000_000_000_000,
504 10_000_000_000_000_000_000,
505 100_000_000_000_000_000_000
506 )]
507 value: u128,
508 ) {
509 let result = fixed_u128_to_f64(value);
510 assert_eq!(result, (value as f64) / FIXED_SCALAR);
511 }
512}
513
514#[cfg(not(feature = "high-precision"))]
515#[cfg(test)]
516mod tests {
517 use nautilus_core::approx_eq;
518 use rstest::rstest;
519
520 use super::*;
521
522 #[rstest]
523 fn test_precision_boundaries() {
524 assert!(check_fixed_precision(0).is_ok());
525 assert!(check_fixed_precision(FIXED_PRECISION).is_ok());
526 assert!(check_fixed_precision(FIXED_PRECISION + 1).is_err());
527 }
528
529 #[rstest]
530 #[case(0.0)]
531 #[case(1.0)]
532 #[case(-1.0)]
533 fn test_basic_roundtrip(#[case] value: f64) {
534 for precision in 0..=FIXED_PRECISION {
535 let fixed = f64_to_fixed_i64(value, precision);
536 let result = fixed_i64_to_f64(fixed);
537 assert!(approx_eq!(f64, value, result, epsilon = 0.001, ulps = 16));
538 }
539 }
540
541 #[rstest]
542 #[case(1000000.0)]
543 #[case(-1000000.0)]
544 fn test_large_value_roundtrip(#[case] value: f64) {
545 for precision in 0..=FIXED_PRECISION {
546 let fixed = f64_to_fixed_i64(value, precision);
547 let result = fixed_i64_to_f64(fixed);
548 assert!(approx_eq!(f64, value, result, epsilon = 0.000_1));
549 }
550 }
551
552 #[rstest]
553 #[case(0, 123456.0, 123456_000000000)]
554 #[case(0, 123456.7, 123457_000000000)]
555 #[case(1, 123456.7, 123456_700000000)]
556 #[case(2, 123456.78, 123456_780000000)]
557 #[case(8, 123456.12345678, 123456_123456780)]
558 #[case(9, 123456.123456789, 123456_123456789)]
559 fn test_precision_specific_values(
560 #[case] precision: u8,
561 #[case] value: f64,
562 #[case] expected: i64,
563 ) {
564 assert_eq!(f64_to_fixed_i64(value, precision), expected);
565 }
566
567 #[rstest]
568 #[case(0.0)]
569 #[case(1.0)]
570 #[case(1000000.0)]
571 fn test_unsigned_basic_roundtrip(#[case] value: f64) {
572 for precision in 0..=FIXED_PRECISION {
573 let fixed = f64_to_fixed_u64(value, precision);
574 let result = fixed_u64_to_f64(fixed);
575 assert!(approx_eq!(f64, value, result, epsilon = 0.001, ulps = 16));
576 }
577 }
578
579 #[rstest]
580 #[case(0, 1.4, 1.0)]
581 #[case(0, 1.5, 2.0)]
582 #[case(0, 1.6, 2.0)]
583 #[case(1, 1.44, 1.4)]
584 #[case(1, 1.45, 1.5)]
585 #[case(1, 1.46, 1.5)]
586 #[case(2, 1.444, 1.44)]
587 #[case(2, 1.445, 1.45)]
588 #[case(2, 1.446, 1.45)]
589 fn test_rounding(#[case] precision: u8, #[case] input: f64, #[case] expected: f64) {
590 let fixed = f64_to_fixed_i128(input, precision);
591 assert!(approx_eq!(
592 f64,
593 fixed_i128_to_f64(fixed),
594 expected,
595 epsilon = 0.000_000_001
596 ));
597 }
598
599 #[rstest]
600 fn test_special_values() {
601 assert_eq!(f64_to_fixed_i128(0.0, FIXED_PRECISION), 0);
603 assert_eq!(f64_to_fixed_i128(-0.0, FIXED_PRECISION), 0);
604
605 let smallest_positive = 1.0 / FIXED_SCALAR;
607 let fixed_smallest = f64_to_fixed_i128(smallest_positive, FIXED_PRECISION);
608 assert_eq!(fixed_smallest, 1);
609
610 let large_int = 1_000_000_000.0;
612 let fixed_large = f64_to_fixed_i128(large_int, 0);
613 assert_eq!(fixed_i128_to_f64(fixed_large), large_int);
614 }
615
616 #[rstest]
617 #[case(0)]
618 #[case(FIXED_PRECISION)]
619 fn test_valid_precision(#[case] precision: u8) {
620 let result = check_fixed_precision(precision);
621 assert!(result.is_ok());
622 }
623
624 #[rstest]
625 fn test_invalid_precision() {
626 let precision = FIXED_PRECISION + 1;
627 let result = check_fixed_precision(precision);
628 assert!(result.is_err());
629 }
630
631 #[rstest]
632 #[case(0, 0.0)]
633 #[case(1, 1.0)]
634 #[case(1, 1.1)]
635 #[case(9, 0.000_000_001)]
636 #[case(0, -0.0)]
637 #[case(1, -1.0)]
638 #[case(1, -1.1)]
639 #[case(9, -0.000_000_001)]
640 fn test_f64_to_fixed_i64_to_fixed(#[case] precision: u8, #[case] value: f64) {
641 let fixed = f64_to_fixed_i64(value, precision);
642 let result = fixed_i64_to_f64(fixed);
643 assert_eq!(result, value);
644 }
645
646 #[rstest]
647 #[case(0, 0.0)]
648 #[case(1, 1.0)]
649 #[case(1, 1.1)]
650 #[case(9, 0.000_000_001)]
651 fn test_f64_to_fixed_u64_to_fixed(#[case] precision: u8, #[case] value: f64) {
652 let fixed = f64_to_fixed_u64(value, precision);
653 let result = fixed_u64_to_f64(fixed);
654 assert_eq!(result, value);
655 }
656
657 #[rstest]
658 #[case(0, 123_456.0, 123_456_000_000_000)]
659 #[case(0, 123_456.7, 123_457_000_000_000)]
660 #[case(0, 123_456.4, 123_456_000_000_000)]
661 #[case(1, 123_456.0, 123_456_000_000_000)]
662 #[case(1, 123_456.7, 123_456_700_000_000)]
663 #[case(1, 123_456.4, 123_456_400_000_000)]
664 #[case(2, 123_456.0, 123_456_000_000_000)]
665 #[case(2, 123_456.7, 123_456_700_000_000)]
666 #[case(2, 123_456.4, 123_456_400_000_000)]
667 fn test_f64_to_fixed_i64_with_precision(
668 #[case] precision: u8,
669 #[case] value: f64,
670 #[case] expected: i64,
671 ) {
672 assert_eq!(f64_to_fixed_i64(value, precision), expected);
673 }
674
675 #[rstest]
676 #[case(0, 5.5, 6_000_000_000)]
677 #[case(1, 5.55, 5_600_000_000)]
678 #[case(2, 5.555, 5_560_000_000)]
679 #[case(3, 5.5555, 5_556_000_000)]
680 #[case(4, 5.55555, 5_555_600_000)]
681 #[case(5, 5.555_555, 5_555_560_000)]
682 #[case(6, 5.555_555_5, 5_555_556_000)]
683 #[case(7, 5.555_555_55, 5_555_555_600)]
684 #[case(8, 5.555_555_555, 5_555_555_560)]
685 #[case(9, 5.555_555_555_5, 5_555_555_556)]
686 #[case(0, -5.5, -6_000_000_000)]
687 #[case(1, -5.55, -5_600_000_000)]
688 #[case(2, -5.555, -5_560_000_000)]
689 #[case(3, -5.5555, -5_556_000_000)]
690 #[case(4, -5.55555, -5_555_600_000)]
691 #[case(5, -5.555_555, -5_555_560_000)]
692 #[case(6, -5.555_555_5, -5_555_556_000)]
693 #[case(7, -5.555_555_55, -5_555_555_600)]
694 #[case(8, -5.555_555_555, -5_555_555_560)]
695 #[case(9, -5.555_555_555_5, -5_555_555_556)]
696 fn test_f64_to_fixed_i64(#[case] precision: u8, #[case] value: f64, #[case] expected: i64) {
697 assert_eq!(f64_to_fixed_i64(value, precision), expected);
698 }
699
700 #[rstest]
701 #[case(0, 5.5, 6_000_000_000)]
702 #[case(1, 5.55, 5_600_000_000)]
703 #[case(2, 5.555, 5_560_000_000)]
704 #[case(3, 5.5555, 5_556_000_000)]
705 #[case(4, 5.55555, 5_555_600_000)]
706 #[case(5, 5.555_555, 5_555_560_000)]
707 #[case(6, 5.555_555_5, 5_555_556_000)]
708 #[case(7, 5.555_555_55, 5_555_555_600)]
709 #[case(8, 5.555_555_555, 5_555_555_560)]
710 #[case(9, 5.555_555_555_5, 5_555_555_556)]
711 fn test_f64_to_fixed_u64(#[case] precision: u8, #[case] value: f64, #[case] expected: u64) {
712 assert_eq!(f64_to_fixed_u64(value, precision), expected);
713 }
714
715 #[rstest]
716 fn test_fixed_i64_to_f64(
717 #[values(1, -1, 2, -2, 10, -10, 100, -100, 1_000, -1_000)] value: i64,
718 ) {
719 assert_eq!(fixed_i64_to_f64(value), value as f64 / FIXED_SCALAR);
720 }
721
722 #[rstest]
723 fn test_fixed_u64_to_f64(
724 #[values(
725 0,
726 1,
727 2,
728 3,
729 10,
730 100,
731 1_000,
732 10_000,
733 100_000,
734 1_000_000,
735 10_000_000,
736 100_000_000,
737 1_000_000_000,
738 10_000_000_000,
739 100_000_000_000,
740 1_000_000_000_000,
741 10_000_000_000_000,
742 100_000_000_000_000,
743 1_000_000_000_000_000
744 )]
745 value: u64,
746 ) {
747 let result = fixed_u64_to_f64(value);
748 assert_eq!(result, (value as f64) / FIXED_SCALAR);
749 }
750}