1
- //! Arbitrary-precision decimal class for fallback algorithms.
1
+ //! Arbitrary-precision decimal type used by fallback algorithms.
2
2
//!
3
3
//! This is only used if the fast-path (native floats) and
4
4
//! the Eisel-Lemire algorithm are unable to unambiguously
11
11
12
12
use crate :: num:: dec2flt:: common:: { is_8digits, ByteSlice } ;
13
13
14
+ /// A decimal floating-point number.
14
15
#[ derive( Clone ) ]
15
16
pub struct Decimal {
16
17
/// The number of significant digits in the decimal.
@@ -30,18 +31,17 @@ impl Default for Decimal {
30
31
}
31
32
32
33
impl Decimal {
33
- /// The maximum number of digits required to unambiguously round a float.
34
+ /// The maximum number of digits required to unambiguously round up to a 64-bit float.
34
35
///
35
- /// For a double-precision IEEE 754 float, this required 767 digits,
36
- /// so we store the max digits + 1.
36
+ /// For an IEEE 754 binary64 float, this required 767 digits. So we store the max digits + 1.
37
37
///
38
38
/// We can exactly represent a float in radix `b` from radix 2 if
39
39
/// `b` is divisible by 2. This function calculates the exact number of
40
40
/// digits required to exactly represent that float.
41
41
///
42
42
/// According to the "Handbook of Floating Point Arithmetic",
43
- /// for IEEE754, with emin being the min exponent, p2 being the
44
- /// precision, and b being the radix, the number of digits follows as:
43
+ /// for IEEE754, with ` emin` being the min exponent, `p2` being the
44
+ /// precision, and `b` being the radix, the number of digits follows as:
45
45
///
46
46
/// `−emin + p2 + ⌊(emin + 1) log(2, b) − log(1 − 2^(−p2), b)⌋`
47
47
///
@@ -56,11 +56,12 @@ impl Decimal {
56
56
/// In Python:
57
57
/// `-emin + p2 + math.floor((emin+ 1)*math.log(2, b)-math.log(1-2**(-p2), b))`
58
58
pub const MAX_DIGITS : usize = 768 ;
59
- /// The max digits that can be exactly represented in a 64-bit integer.
59
+ /// The max decimal digits that can be exactly represented in a 64-bit integer.
60
60
pub const MAX_DIGITS_WITHOUT_OVERFLOW : usize = 19 ;
61
61
pub const DECIMAL_POINT_RANGE : i32 = 2047 ;
62
62
63
- /// Append a digit to the buffer.
63
+ /// Append a digit to the buffer if it fits.
64
+ // TODO: looks like this
64
65
pub fn try_add_digit ( & mut self , digit : u8 ) {
65
66
if self . num_digits < Self :: MAX_DIGITS {
66
67
self . digits [ self . num_digits ] = digit;
@@ -69,6 +70,7 @@ impl Decimal {
69
70
}
70
71
71
72
/// Trim trailing zeros from the buffer.
73
+ // TODO: switch to `.rev().position()`
72
74
pub fn trim ( & mut self ) {
73
75
// All of the following calls to `Decimal::trim` can't panic because:
74
76
//
@@ -86,7 +88,7 @@ impl Decimal {
86
88
pub fn round ( & self ) -> u64 {
87
89
if self . num_digits == 0 || self . decimal_point < 0 {
88
90
return 0 ;
89
- } else if self . decimal_point > 18 {
91
+ } else if self . decimal_point >= Self :: MAX_DIGITS_WITHOUT_OVERFLOW as i32 {
90
92
return 0xFFFF_FFFF_FFFF_FFFF_u64 ;
91
93
}
92
94
let dp = self . decimal_point as usize ;
0 commit comments