Skip to content

Commit 8d8c8be

Browse files
authored
optimize (#413)
1 parent 4813637 commit 8d8c8be

2 files changed

Lines changed: 41 additions & 24 deletions

File tree

source/mir/bignum/internal/dec2float.d

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -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

480500
private 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)

source/mir/bignum/internal/dec2float_table.d

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2063,7 +2063,6 @@ static immutable align(16) ulong[1025] p10_coefficients_h = [
20632063
0xE319A0AEA60E91C7,
20642064
];
20652065

2066-
static if (real.mant_dig >= 64)
20672066
static immutable align(16) ulong[1025] p10_coefficients_l = [
20682067
0x7132D332E3F204D5,
20692068
0x8D7F87FF9CEE860A,

0 commit comments

Comments
 (0)