@@ -3,6 +3,25 @@ use crate::float::Float;
3
3
4
4
const MIN_19DIGIT_INT : u64 = 100_0000_0000_0000_0000 ;
5
5
6
+ pub const INT_POW10 : [ u64 ; 16 ] = [
7
+ 1 ,
8
+ 10 ,
9
+ 100 ,
10
+ 1000 ,
11
+ 10000 ,
12
+ 100000 ,
13
+ 1000000 ,
14
+ 10000000 ,
15
+ 100000000 ,
16
+ 1000000000 ,
17
+ 10000000000 ,
18
+ 100000000000 ,
19
+ 1000000000000 ,
20
+ 10000000000000 ,
21
+ 100000000000000 ,
22
+ 1000000000000000 ,
23
+ ] ;
24
+
6
25
#[ derive( Clone , Copy , Debug , Default , PartialEq , Eq ) ]
7
26
pub struct Number {
8
27
pub exponent : i64 ,
@@ -15,20 +34,31 @@ impl Number {
15
34
#[ inline]
16
35
fn is_fast_path < F : Float > ( & self ) -> bool {
17
36
F :: MIN_EXPONENT_FAST_PATH <= self . exponent
18
- && self . exponent <= F :: MAX_EXPONENT_FAST_PATH
37
+ && self . exponent <= F :: MAX_EXPONENT_DISGUISED_FAST_PATH
19
38
&& self . mantissa <= F :: MAX_MANTISSA_FAST_PATH
20
39
&& !self . many_digits
21
40
}
22
41
23
42
#[ inline]
24
43
pub fn try_fast_path < F : Float > ( & self ) -> Option < F > {
25
44
if self . is_fast_path :: < F > ( ) {
26
- let mut value = F :: from_u64 ( self . mantissa ) ;
27
- if self . exponent < 0 {
28
- value = value / F :: pow10_fast_path ( ( -self . exponent ) as _ ) ;
45
+ let mut value = if self . exponent <= F :: MAX_EXPONENT_FAST_PATH {
46
+ // normal fast path
47
+ let value = F :: from_u64 ( self . mantissa ) ;
48
+ if self . exponent < 0 {
49
+ value / F :: pow10_fast_path ( ( -self . exponent ) as _ )
50
+ } else {
51
+ value * F :: pow10_fast_path ( self . exponent as _ )
52
+ }
29
53
} else {
30
- value = value * F :: pow10_fast_path ( self . exponent as _ ) ;
31
- }
54
+ // disguised fast path
55
+ let shift = self . exponent - F :: MAX_EXPONENT_FAST_PATH ;
56
+ let mantissa = self . mantissa . checked_mul ( INT_POW10 [ shift as usize ] ) ?;
57
+ if mantissa > F :: MAX_MANTISSA_FAST_PATH {
58
+ return None ;
59
+ }
60
+ F :: from_u64 ( mantissa) * F :: pow10_fast_path ( F :: MAX_EXPONENT_FAST_PATH as _ )
61
+ } ;
32
62
if self . negative {
33
63
value = -value;
34
64
}
0 commit comments