@@ -46,11 +46,11 @@ struct Decimal(size_t maxSize64)
4646 }
4747
4848 // /
49-  this (C)(scope  const (C)[] str) @safe  pure  @nogc 
49+  this (C)(scope  const (C)[] str,  int  exponentShift =  0 ) @safe  pure  @nogc 
5050 if  (isSomeChar! C)
5151 {
5252 DecimalExponentKey key;
53-  if  (fromStringImpl(str, key) ||  key ==  DecimalExponentKey.nan ||  key ==  DecimalExponentKey.infinity)
53+  if  (fromStringImpl(str, key, exponentShift ) ||  key ==  DecimalExponentKey.nan ||  key ==  DecimalExponentKey.infinity)
5454 return ;
5555 static  if  (__traits(compiles, () @nogc  { throw  new  Exception (" Can't parse Decimal."  ); }))
5656 {
@@ -119,7 +119,16 @@ struct Decimal(size_t maxSize64)
119119 Returns: false in case of overflow or incorrect string. 
120120 Precondition: non-empty coefficients. 
121121 +/  
122-  bool  fromStringImpl (C, bool  allowSpecialValues = true , bool  allowDotOnBounds = true , bool  allowDExponent = true , bool  allowStartingPlus = true , bool  checkEmpty = true , bool  allowUnderscores = true , bool  allowLeadingZeros = true )(scope  const (C)[] str, out  DecimalExponentKey key)
122+  bool  fromStringImpl (C,
123+  bool  allowSpecialValues = true ,
124+  bool  allowDotOnBounds = true ,
125+  bool  allowDExponent = true ,
126+  bool  allowStartingPlus = true ,
127+  bool  allowUnderscores = true ,
128+  bool  allowLeadingZeros = true ,
129+  bool  checkEmpty = true ,
130+  )
131+  (scope  const (C)[] str, out  DecimalExponentKey key, int  exponentShift = 0 )
123132 @safe  pure  @nogc  nothrow 
124133 if  (isSomeChar! C)
125134 {
@@ -161,7 +170,6 @@ struct Decimal(size_t maxSize64)
161170 exponent = 0 ;
162171
163172 ulong  v;
164-  uint  afterDot;
165173 bool  dot;
166174 static  if  (allowUnderscores)
167175 {
@@ -225,11 +233,11 @@ struct Decimal(size_t maxSize64)
225233 }
226234 S:
227235 v +=  d;
228-  afterDot  + =  dot;
236+  exponentShift  - =  dot;
229237 if  (str.length)
230238 continue ;
231239 E:
232-  exponent -=  afterDot ;
240+  exponent +=  exponentShift ;
233241 R:
234242 coefficient.data[0 ] = v;
235243 coefficient.length = v !=  0 ;
@@ -321,7 +329,7 @@ struct Decimal(size_t maxSize64)
321329 {
322330 import  mir.bignum.low_level_view: DecimalView, BigUIntView, MaxWordPow10;
323331 auto  work = DecimalView! size_t (false , 0 , BigUIntView! size_t (coefficient.data));
324-  auto  ret = work.fromStringImpl! (C, allowSpecialValues, allowDExponent, allowStartingPlus, checkEmpty,  allowUnderscores, allowLeadingZeros)(str, key);
332+  auto  ret = work.fromStringImpl! (C, allowSpecialValues, allowDExponent, allowStartingPlus, allowUnderscores, allowLeadingZeros, checkEmpty )(str, key, exponentShift );
325333 coefficient.length = cast (uint ) work.coefficient.coefficients.length;
326334 coefficient.sign = work.sign;
327335 exponent = work.exponent;
@@ -339,9 +347,11 @@ struct Decimal(size_t maxSize64)
339347 Decimal! 3  decimal;
340348 DecimalExponentKey key;
341349
342-  assert (decimal.fromStringImpl(" 1.334"  , key));
350+  //  Check precise percentate parsing
351+  assert (decimal.fromStringImpl(" 71.7"  , key, - 2 ));
343352 assert (key ==  DecimalExponentKey.dot);
344-  assert (cast (double ) decimal ==  1.334 );
353+  //  The result is exact value instead of 0.7170000000000001 = 71.7 / 100
354+  assert (cast (double ) decimal ==  0.717 );
345355
346356 assert (decimal.fromStringImpl(" +0.334e-5"  w, key));
347357 assert (key ==  DecimalExponentKey.e);
0 commit comments