@@ -494,11 +494,11 @@ class dd {
494
494
std::vector<char > t;
495
495
496
496
if (fixed) {
497
- t.resize (nrDigitsForFixedFormat+1 );
497
+ t.resize (static_cast < size_t >( nrDigitsForFixedFormat+1 ) );
498
498
to_digits (t, e, nrDigitsForFixedFormat);
499
499
}
500
500
else {
501
- t.resize (nrDigits+1 );
501
+ t.resize (static_cast < size_t >( nrDigits+1 ) );
502
502
to_digits (t, e, nrDigits);
503
503
}
504
504
@@ -508,30 +508,32 @@ class dd {
508
508
509
509
if (integerDigits > 0 ) {
510
510
int i;
511
- for (i = 0 ; i < integerDigits; ++i) s += t[i ];
511
+ for (i = 0 ; i < integerDigits; ++i) s += t[static_cast < unsigned >(i) ];
512
512
if (precision > 0 ) {
513
513
s += ' .' ;
514
- for (int j = 0 ; j < precision; ++j, ++i) s += t[i ];
514
+ for (int j = 0 ; j < precision; ++j, ++i) s += t[static_cast < unsigned >(i) ];
515
515
}
516
516
}
517
517
else {
518
518
s += " 0." ;
519
519
if (integerDigits < 0 ) s.append (static_cast <size_t >(-integerDigits), ' 0' );
520
- for (int i = 0 ; i < nrDigits; ++i) s += t[i ];
520
+ for (int i = 0 ; i < nrDigits; ++i) s += t[static_cast < unsigned >(i) ];
521
521
}
522
522
}
523
523
else {
524
- s += t[0 ];
524
+ s += t[0ull ];
525
525
if (precision > 0 ) s += ' .' ;
526
526
527
527
for (int i = 1 ; i <= precision; ++i)
528
- s += t[i ];
528
+ s += t[static_cast < unsigned >(i) ];
529
529
530
530
}
531
531
}
532
532
}
533
533
534
- // trap for improper offset with large values
534
+ // TBD: this is seriously broken and needs a redesign
535
+ //
536
+ // fix for improper offset with large values and small values
535
537
// without this trap, output of values of the for 10^j - 1 fail for j > 28
536
538
// and are output with the point in the wrong place, leading to a significant error
537
539
if (fixed && (precision > 0 )) {
@@ -546,17 +548,18 @@ class dd {
546
548
for (std::string::size_type i = 1 ; i < s.length (); ++i) {
547
549
if (s[i] == ' .' ) {
548
550
s[i] = s[i - 1 ];
549
- s[i - 1 ] = ' .' ;
551
+ s[i - 1 ] = ' .' ; // this will destroy the leading 0 when s[i==1] == '.';
550
552
break ;
551
553
}
552
554
}
553
555
// BUG: the loop above, in particular s[i-1] = '.', destroys the leading 0
554
556
// in the fixed point representation if the point is located at i = 1;
557
+ // it also breaks the precision request as it adds a new digit to the fixed representation
555
558
556
559
from_string = atof (s.c_str ());
557
560
// if this ratio is large, then the string has not been fixed
558
561
if (std::fabs (from_string / hi) > 3.0 ) {
559
- std::cerr << " re-rounding unsuccessful in large number fixed point trap \n " ;
562
+ std::cerr << " re-rounding unsuccessful in fixed point fix \n " ;
560
563
}
561
564
}
562
565
}
@@ -670,22 +673,22 @@ class dd {
670
673
int nrDigits = precision;
671
674
// round decimal string and propagate carry
672
675
int lastDigit = nrDigits - 1 ;
673
- if (s[lastDigit] >= ' 5' ) {
676
+ if (s[static_cast < unsigned >( lastDigit) ] >= ' 5' ) {
674
677
if constexpr (bTraceDecimalRounding) std::cout << " need to round\n " ;
675
678
int i = nrDigits - 2 ;
676
- s[i ]++;
677
- while (i > 0 && s[i ] > ' 9' ) {
678
- s[i ] -= 10 ;
679
- s[--i]++;
679
+ s[static_cast < unsigned >(i) ]++;
680
+ while (i > 0 && s[static_cast < unsigned >(i) ] > ' 9' ) {
681
+ s[static_cast < unsigned >(i) ] -= 10 ;
682
+ s[static_cast < unsigned >( --i) ]++;
680
683
}
681
684
}
682
685
683
686
// if first digit is 10, shift everything.
684
687
if (s[0 ] > ' 9' ) {
685
688
if constexpr (bTraceDecimalRounding) std::cout << " shift right to handle overflow\n " ;
686
- for (int i = precision; i >= 2 ; --i) s[i ] = s[i - 1 ];
687
- s[0 ] = ' 1' ;
688
- s[1 ] = ' 0' ;
689
+ for (int i = precision; i >= 2 ; --i) s[static_cast < unsigned >(i) ] = s[static_cast < unsigned >( i - 1 ) ];
690
+ s[0u ] = ' 1' ;
691
+ s[1u ] = ' 0' ;
689
692
690
693
(*decimalPoint)++; // increment decimal point
691
694
++precision;
@@ -722,7 +725,7 @@ class dd {
722
725
723
726
if (iszero ()) {
724
727
exponent = 0 ;
725
- for (int i = 0 ; i < precision; ++i) s[i ] = ' 0' ;
728
+ for (int i = 0 ; i < precision; ++i) s[static_cast < unsigned >(i) ] = ' 0' ;
726
729
return ;
727
730
}
728
731
@@ -781,20 +784,20 @@ class dd {
781
784
r -= mostSignificantDigit;
782
785
r *= 10.0 ;
783
786
784
- s[i ] = static_cast <char >(mostSignificantDigit + ' 0' );
787
+ s[static_cast < unsigned >(i) ] = static_cast <char >(mostSignificantDigit + ' 0' );
785
788
if constexpr (bTraceDecimalConversion) std::cout << " to_digits digit[" << i << " ] : " << s << ' \n ' ;
786
789
}
787
790
788
791
// Fix out of range digits
789
792
for (int i = nrDigits - 1 ; i > 0 ; --i) {
790
- if (s[i ] < ' 0' ) {
791
- s[i - 1 ]--;
792
- s[i ] += 10 ;
793
+ if (s[static_cast < unsigned >(i) ] < ' 0' ) {
794
+ s[static_cast < unsigned >( i - 1 ) ]--;
795
+ s[static_cast < unsigned >(i) ] += 10 ;
793
796
}
794
797
else {
795
- if (s[i ] > ' 9' ) {
796
- s[i - 1 ]++;
797
- s[i ] -= 10 ;
798
+ if (s[static_cast < unsigned >(i) ] > ' 9' ) {
799
+ s[static_cast < unsigned >( i - 1 ) ]++;
800
+ s[static_cast < unsigned >(i) ] -= 10 ;
798
801
}
799
802
}
800
803
}
@@ -806,26 +809,26 @@ class dd {
806
809
807
810
// Round and propagate carry
808
811
int lastDigit = nrDigits - 1 ;
809
- if (s[lastDigit] >= ' 5' ) {
812
+ if (s[static_cast < unsigned >( lastDigit) ] >= ' 5' ) {
810
813
int i = nrDigits - 2 ;
811
- s[i ]++;
812
- while (i > 0 && s[i ] > ' 9' ) {
813
- s[i ] -= 10 ;
814
- s[--i]++;
814
+ s[static_cast < unsigned >(i) ]++;
815
+ while (i > 0 && s[static_cast < unsigned >(i) ] > ' 9' ) {
816
+ s[static_cast < unsigned >(i) ] -= 10 ;
817
+ s[static_cast < unsigned >( --i) ]++;
815
818
}
816
819
}
817
820
818
821
// If first digit is 10, shift left and increment exponent
819
822
if (s[0 ] > ' 9' ) {
820
823
++e;
821
824
for (int i = precision; i >= 2 ; --i) {
822
- s[i ] = s[i - 1 ];
825
+ s[static_cast < unsigned >(i) ] = s[static_cast < unsigned >( i - 1 ) ];
823
826
}
824
827
s[0 ] = ' 1' ;
825
828
s[1 ] = ' 0' ;
826
829
}
827
830
828
- s[precision] = 0 ; // termination null
831
+ s[static_cast < unsigned >( precision) ] = 0 ; // termination null
829
832
exponent = e;
830
833
}
831
834
0 commit comments