@@ -122,40 +122,58 @@ T decimalToFloatImpl(T)(ulong coefficient, long exponent)
122122
123123 enum wordBits = T.mant_dig < 64 ? 64 : 128 ;
124124 enum ulong half = (1UL << (wordBits - T.mant_dig - 1 ));
125+ enum bigHalf = UInt! 128 ([0UL , half]);
126+ enum bigMask = (1UL << (64 - T.mant_dig)) - 1 ;
127+
125128 static if (T.mant_dig > 64 )
126129 enum ulong mask = (1UL << (128 - T.mant_dig)) - 1 ;
127130 else
128131 static if (T.mant_dig == 64 )
129132 enum ulong mask = ulong .max;
130133 else
131- enum ulong mask = ( 1UL << ( 64 - T.mant_dig)) - 1 ;
134+ enum ulong mask = bigMask ;
132135
133136 if (coefficient == 0 )
134137 return 0 ;
135138
136139 version (TeslAlgoM) {} else
137140 if (_expect(- ExponentM <= exponent && exponent <= ExponentM, true ))
138141 {
139- auto c = coefficient.Fp! 64 ;
140- auto z = c.extendedMul! true (_load! T(exponent));
141- auto approx = z.opCast ! (T, true );
142- long bitsDiff = (cast (ulong ) z.opCast ! (Fp! wordBits).coefficient & mask) - half;
143- int slop = 3 * (exponent < 0 );
144- if (_expect(approx > T.min_normal && (bitsDiff < 0 ? - bitsDiff : bitsDiff) > slop, true ))
145- return approx;
146-
147- if (0 <= exponent)
148- {
149- if (exponent <= MaxWordPow5! ulong )
142+ version (all )
143+ {{
144+ auto c = coefficient.Fp! 64 ;
145+ auto z = c.extendedMul! true (_load! wordBits(exponent));
146+ auto approx = z.opCast ! (T, true );
147+ long bitsDiff = (cast (ulong ) z.opCast ! (Fp! wordBits).coefficient & mask) - half;
148+ uint slop = 3 * (exponent < 0 );
149+ if (_expect(approx > T.min_normal && (bitsDiff < 0 ? - bitsDiff : bitsDiff) > slop, true ))
150150 return approx;
151- }
152- else
153- {
154- if (- exponent <= MaxFpPow5! T)
151+
152+ if (0 <= exponent)
155153 {
156- auto e = _load ! T( - exponent);
157- return coefficient / e. opCast ! (T, true ) ;
154+ if (exponent <= MaxWordPow5 ! ulong )
155+ return approx ;
158156 }
157+ else
158+ {
159+ if (- exponent <= MaxFpPow5! T)
160+ {
161+ auto e = _load! wordBits(- exponent);
162+ return coefficient / e.opCast ! (T, true );
163+ }
164+ }
165+ }}
166+ static if (T.mant_dig < 64 )
167+ {
168+ auto c = coefficient.Fp! 64 ;
169+ auto z = c.extendedMul! true (_load! 128 (exponent));
170+ auto approx = z.opCast ! (T, true );
171+ auto bitsDiff = (z.opCast ! (Fp! 128 ).coefficient & bigMask) - bigHalf;
172+ if (bitsDiff.signBit)
173+ bitsDiff = UInt! 128. init - bitsDiff;
174+ uint slop = 3 * (exponent < 0 );
175+ if (_expect(approx > T.min_normal && bitsDiff > slop, true ))
176+ return approx;
159177 }
160178 }
161179 size_t [ulong .sizeof / size_t .sizeof] coefficients;
@@ -206,7 +224,7 @@ private T decimalToFloatImpl(T)(scope const size_t[] coefficients, long exponent
206224 if (_expect(- ExponentM <= exponent && exponent <= ExponentM, true ))
207225 {
208226 auto c = coefficients.binaryToFp! wordBits;
209- auto z = c.extendedMul! true (_load! T (exponent));
227+ auto z = c.extendedMul! true (_load! wordBits (exponent));
210228 auto approx = z.opCast ! (T, true );
211229 auto slop = 1 + 3 * (exponent < 0 );
212230 long bitsDiff = (cast (ulong ) z.opCast ! (Fp! wordBits).coefficient & mask) - half;
@@ -241,6 +259,8 @@ private T algorithmM(T)(scope const size_t[] coefficients, long exponent)
241259{
242260 pragma (inline, false );
243261
262+ // import mir.stdio;
263+ // debug dump("algorithmM", coefficients, exponent);
244264
245265 import mir.bitop: ctlz;
246266 import mir.bignum.fp: Fp;
@@ -479,8 +499,7 @@ package(mir.bignum) auto binaryToFp(uint coefficientSize, uint internalRoundLast
479499
480500private enum ExponentM = 512 ;
481501
482- private auto _load (T)(long e) @trusted
483- if (T.mant_dig < 64 )
502+ private auto _load (uint size : 64 )(long e) @trusted
484503 in (- ExponentM < e && e < ExponentM)
485504{
486505 version (LDC )
@@ -496,8 +515,7 @@ private auto _load(T)(long e) @trusted
496515 return Fp! 64 (false , p10exp, UInt! 64 (p10coeff));
497516}
498517
499- private auto _load (T)(long e) @trusted
500- if (T.mant_dig >= 64 )
518+ private auto _load (uint size : 128 )(long e) @trusted
501519 in (- ExponentM < e && e < ExponentM)
502520{
503521 version (LDC )
0 commit comments