@@ -213,11 +213,11 @@ struct Decimal(uint size64)
213213 }
214214 }
215215
216- uint d = str[0 ] - ' 0' ;
216+ ulong d = str[0 ] - C( ' 0' ) ;
217217 str = str[1 .. $];
218218 exponent = 0 ;
219219
220- ulong v;
220+ ulong v, multplier = void ;
221221
222222 if (_expect(d >= 10 , false ))
223223 {
@@ -228,7 +228,7 @@ struct Decimal(uint size64)
228228 if (str.length == 0 )
229229 return false ;
230230 key = DecimalExponentKey.dot;
231- d = str[0 ] - ' 0' ;
231+ d = str[0 ] - C( ' 0' ) ;
232232 str = str[1 .. $];
233233 if (_expect(d < 10 , true ))
234234 goto FI ;
@@ -247,7 +247,7 @@ struct Decimal(uint size64)
247247 {
248248 if (str.length == 0 )
249249 goto R;
250- d = str[0 ] - ' 0' ;
250+ d = str[0 ] - C( ' 0' ) ;
251251 str = str[1 .. $];
252252 if (d < 10 )
253253 return false ;
@@ -260,15 +260,15 @@ struct Decimal(uint size64)
260260 S:
261261 if (str.length == 0 )
262262 goto R;
263- d = str[0 ] - ' 0' ;
263+ d = str[0 ] - C( ' 0' ) ;
264264 str = str[1 .. $];
265265
266266 if (d < 10 )
267267 {
268268 F0 :
269269 import mir.checkedint: mulu, addu;
270270 bool overflow;
271- v = mulu(v, cast ( uint ) 10 , overflow);
271+ v = mulu(v, 10u , overflow);
272272 if (overflow)
273273 return false ;
274274 v = addu(v, d, overflow);
@@ -283,7 +283,7 @@ struct Decimal(uint size64)
283283 {
284284 if (str.length == 0 )
285285 return false ;
286- d = str[0 ] - ' 0' ;
286+ d = str[0 ] - C( ' 0' ) ;
287287 str = str[1 .. $];
288288 if (_expect(d < 10 , true ))
289289 goto F0 ;
@@ -314,51 +314,76 @@ struct Decimal(uint size64)
314314 import mir.bignum.internal.parse: isMadeOfEightDigits, parseEightDigits;
315315 if (str.length >= 8 && isMadeOfEightDigits(str[0 .. 8 ]))
316316 {
317- ulong multplier = 100000000 ;
318- ulong value = parseEightDigits(str[0 .. 8 ]);
317+ multplier = 100000000 ;
318+ d = parseEightDigits(str[0 .. 8 ]);
319319 str = str[8 .. $];
320320 exponentShift -= 8 ;
321- if (str.length >= 8 && isMadeOfEightDigits(str[ 0 .. 8 ]) )
321+ if (str.length >= 7 )
322322 {
323- multplier = 100000000 * 100000000 ;
324- value *= 100000000 ;
325- value += parseEightDigits(str[0 .. 8 ]);
326- str = str[8 .. $];
327- exponentShift -= 8 ;
328- }
329-
330- {
331- import mir.checkedint: mulu, addu;
332- bool overflow;
333- v = mulu(v, multplier, overflow);
334- if (overflow)
335- return false ;
336- v = addu(v, value, overflow);
337- if (overflow)
338- return false ;
323+ if (isMadeOfEightDigits((str.ptr - 1 )[0 .. 8 ]))
324+ {
325+ multplier = 100000000 * 10000000 ;
326+ d -= str.ptr[- 1 ] - ' 0' ;
327+ d *= 10000000 ;
328+ d += parseEightDigits((str.ptr - 1 )[0 .. 8 ]);
329+ str = str[7 .. $];
330+ exponentShift -= 7 ;
331+ if (str.length)
332+ {
333+ auto md = str[0 ] - C(' 0' );
334+ if (md < 10 )
335+ {
336+ d *= 10 ;
337+ multplier = 100000000 * 100000000 ;
338+ d += md;
339+ str = str[1 .. $];
340+ }
341+ }
342+ }
343+ else
344+ {
345+ TrySix:
346+ if (isMadeOfEightDigits((str.ptr - 2 )[0 .. 8 ]))
347+ {
348+ multplier = 100000000 * 1000000 ;
349+ d -= str.ptr[- 1 ] - ' 0' ;
350+ d -= (str.ptr[- 2 ] - ' 0' ) * 10 ;
351+ d *= 1000000 ;
352+ d += parseEightDigits((str.ptr - 2 )[0 .. 8 ]);
353+ str = str[6 .. $];
354+ exponentShift -= 6 ;
355+ }
356+ }
357+
339358 }
359+ else
360+ if (str.length == 6 )
361+ goto TrySix;
362+ goto FIL ;
340363 }
341364 }
342365
343- d = str[0 ] - ' 0' ;
366+ d = str[0 ] - C( ' 0' ) ;
344367 str = str[1 .. $];
345368 if (_expect(d >= 10 , false ))
346369 goto DOB ;
347370 FI :
371+ exponentShift-- ;
372+ multplier = 10 ;
373+ FIL :
348374 {
349375 import mir.checkedint: mulu, addu;
350376 bool overflow;
351- v = mulu(v, cast ( uint ) 10 , overflow);
377+ v = mulu(v, multplier , overflow);
352378 if (overflow)
353379 return false ;
354380 v = addu(v, d, overflow);
355381 if (overflow)
356382 return false ;
357383 }
358- exponentShift-- ;
359384 if (str.length == 0 )
360385 goto E;
361- d = str[0 ] - ' 0' ;
386+ d = str[0 ] - C( ' 0' ) ;
362387 str = str[1 .. $];
363388 if (d < 10 )
364389 goto FI ;
@@ -369,7 +394,7 @@ struct Decimal(uint size64)
369394 {
370395 if (str.length == 0 )
371396 return false ;
372- d = str[0 ] - ' 0' ;
397+ d = str[0 ] - C( ' 0' ) ;
373398 str = str[1 .. $];
374399 if (_expect(d < 10 , true ))
375400 goto FI ;
@@ -817,42 +842,43 @@ unittest
817842
818843 // Check precise percentate parsing
819844 assert (decimal.fromStringImpl(" 71.7" , key, - 2 ));
820- assert ( key == DecimalExponentKey.dot) ;
845+ key.should == DecimalExponentKey.dot;
821846 // The result is exact value instead of 0.7170000000000001 = 71.7 / 100
822- assert (cast (double ) decimal == 0.717 ) ;
847+ (cast (double ) decimal).should == 0.717 ;
823848
824849 assert (decimal.fromStringImpl(" +0.334e-5" w, key));
825- assert ( key == DecimalExponentKey.e) ;
826- assert (cast (double ) decimal == 0.334e-5 ) ;
850+ key.should == DecimalExponentKey.e;
851+ (cast (double ) decimal).should == 0.334e-5 ;
827852
828853 assert (decimal.fromStringImpl(" 100_000_000" w, key));
829- assert ( key == DecimalExponentKey.none) ;
830- assert (cast (double ) decimal == 1e8 ) ;
854+ key.should == DecimalExponentKey.none;
855+ (cast (double ) decimal).should == 1e8 ;
831856
832857 assert (decimal.fromStringImpl(" -334D-5" d, key));
833- assert ( key == DecimalExponentKey.D) ;
834- assert (cast (double ) decimal == - 334e-5 ) ;
858+ key.should == DecimalExponentKey.D;
859+ (cast (double ) decimal).should == - 334e-5 ;
835860
836861 assert (decimal.fromStringImpl(" 2482734692817364218734682973648217364981273648923423" , key));
837- assert ( key == DecimalExponentKey.none) ;
838- assert (cast (double ) decimal == 2482734692817364218734682973648217364981273648923423.0 ) ;
862+ key.should == DecimalExponentKey.none;
863+ (cast (double ) decimal).should == 2482734692817364218734682973648217364981273648923423.0 ;
839864
840865 assert (decimal.fromStringImpl(" .023" , key));
841- assert ( key == DecimalExponentKey.dot) ;
842- assert (cast (double ) decimal == .023 ) ;
866+ key.should == DecimalExponentKey.dot;
867+ (cast (double ) decimal).should == .023 ;
843868
844869 assert (decimal.fromStringImpl(" 0E100" , key));
845- assert ( key == DecimalExponentKey.E) ;
846- assert (cast (double ) decimal == 0 ) ;
870+ key.should == DecimalExponentKey.E;
871+ (cast (double ) decimal).should == 0 ;
847872
848873 foreach (str; [" -nan" , " -NaN" , " -NAN" ])
849874 {
850875 assert (decimal.fromStringImpl(str, key));
851876 assert (decimal.coefficient.length > 0 );
852877 assert (decimal.exponent == decimal.exponent.max);
853878 assert (decimal.coefficient.sign);
854- assert (key == DecimalExponentKey.nan);
855- assert (cast (double ) decimal != cast (double ) decimal);
879+ key.should == DecimalExponentKey.nan;
880+ auto nan = cast (double ) decimal;
881+ (cast (double ) decimal).should == double .nan;
856882 }
857883
858884 foreach (str; [" inf" , " Inf" , " INF" ])
@@ -861,7 +887,7 @@ unittest
861887 assert (decimal.coefficient.length == 0 );
862888 assert (decimal.exponent == decimal.exponent.max);
863889 assert (key == DecimalExponentKey.infinity);
864- assert (cast (double ) decimal == double .infinity) ;
890+ (cast (double ) decimal).should == double .infinity;
865891 }
866892
867893 assert (decimal.fromStringImpl(" -inf" , key));
0 commit comments