@@ -59,22 +59,41 @@ export function isE(number: string | number) {
5959 return ! Number . isNaN ( Number ( str ) ) && str . includes ( 'e' ) ;
6060}
6161
62- export function expandScientificNotation ( numStr : string ) {
63- const [ mantissa , exponent ] = numStr . toLowerCase ( ) . split ( 'e' ) ;
64- const exp = Number ( exponent ) ;
62+ type ParsedScientificNotation = {
63+ decimal : string ;
64+ digits : string ;
65+ exponent : number ;
66+ integer : string ;
67+ negative : boolean ;
68+ } ;
69+
70+ function parseScientificNotation ( numStr : string ) : ParsedScientificNotation {
71+ const [ mantissa , exponent = '0' ] = numStr . toLowerCase ( ) . split ( 'e' ) ;
6572 const negative = mantissa . startsWith ( '-' ) ;
6673 const unsignedMantissa = negative ? mantissa . slice ( 1 ) : mantissa ;
6774 const [ integer = '0' , decimal = '' ] = unsignedMantissa . split ( '.' ) ;
6875 const digits = `${ integer } ${ decimal } ` . replace ( / ^ 0 + / , '' ) || '0' ;
6976
77+ return {
78+ decimal,
79+ digits,
80+ exponent : Number ( exponent ) ,
81+ integer,
82+ negative,
83+ } ;
84+ }
85+
86+ function expandScientificNotation ( parsed : ParsedScientificNotation ) {
87+ const { decimal, digits, exponent, integer, negative } = parsed ;
88+
7089 if ( digits === '0' ) {
7190 return '0' ;
7291 }
7392
7493 const integerDigits = integer . replace ( / ^ 0 + / , '' ) . length ;
7594 const leadingDecimalZeros = ( decimal . match ( / ^ 0 * / ) || [ '' ] ) [ 0 ] . length ;
7695 const initialDecimalIndex = integerDigits || - leadingDecimalZeros ;
77- const decimalIndex = initialDecimalIndex + exp ;
96+ const decimalIndex = initialDecimalIndex + exponent ;
7897
7998 let expanded = '' ;
8099
@@ -89,6 +108,14 @@ export function expandScientificNotation(numStr: string) {
89108 return `${ negative ? '-' : '' } ${ expanded } ` ;
90109}
91110
111+ function getScientificPrecision ( parsed : ParsedScientificNotation ) {
112+ if ( parsed . exponent >= 0 ) {
113+ return Math . max ( 0 , parsed . decimal . length - parsed . exponent ) ;
114+ }
115+
116+ return Math . abs ( parsed . exponent ) + parsed . decimal . length ;
117+ }
118+
92119/**
93120 * [Legacy] Convert 1e-9 to 0.000000001.
94121 * This may lose some precision if user really want 1e-9.
@@ -97,16 +124,7 @@ export function getNumberPrecision(number: string | number) {
97124 const numStr : string = String ( number ) ;
98125
99126 if ( isE ( number ) ) {
100- const [ mantissa , exponent = '0' ] = numStr . toLowerCase ( ) . split ( 'e' ) ;
101- const decimalMatch = mantissa . match ( / \. ( \d + ) / ) ;
102- const decimalLength = decimalMatch ?. [ 1 ] ?. length || 0 ;
103- const exp = Number ( exponent ) ;
104-
105- if ( exp >= 0 ) {
106- return Math . max ( 0 , decimalLength - exp ) ;
107- }
108-
109- return Math . abs ( exp ) + decimalLength ;
127+ return getScientificPrecision ( parseScientificNotation ( numStr ) ) ;
110128 }
111129
112130 return numStr . includes ( '.' ) && validateNumber ( numStr )
@@ -132,12 +150,11 @@ export function num2str(number: number): string {
132150 ) ;
133151 }
134152
135- const precision = getNumberPrecision ( numStr ) ;
153+ const parsed = parseScientificNotation ( numStr ) ;
154+ const precision = getScientificPrecision ( parsed ) ;
136155
137156 numStr =
138- precision > 100
139- ? expandScientificNotation ( numStr )
140- : number . toFixed ( precision ) ;
157+ precision > 100 ? expandScientificNotation ( parsed ) : number . toFixed ( precision ) ;
141158 }
142159
143160 return trimNumber ( numStr ) . fullStr ;
0 commit comments