@@ -3,6 +3,25 @@ use crate::float::Float;
33
44const MIN_19DIGIT_INT : u64 = 100_0000_0000_0000_0000 ;
55
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+
625#[ derive( Clone , Copy , Debug , Default , PartialEq , Eq ) ]
726pub struct Number {
827 pub exponent : i64 ,
@@ -15,20 +34,31 @@ impl Number {
1534 #[ inline]
1635 fn is_fast_path < F : Float > ( & self ) -> bool {
1736 F :: MIN_EXPONENT_FAST_PATH <= self . exponent
18- && self . exponent <= F :: MAX_EXPONENT_FAST_PATH
37+ && self . exponent <= F :: MAX_EXPONENT_DISGUISED_FAST_PATH
1938 && self . mantissa <= F :: MAX_MANTISSA_FAST_PATH
2039 && !self . many_digits
2140 }
2241
2342 #[ inline]
2443 pub fn try_fast_path < F : Float > ( & self ) -> Option < F > {
2544 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+ }
2953 } 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+ } ;
3262 if self . negative {
3363 value = -value;
3464 }
0 commit comments