Skip to content

Commit b6bdb63

Browse files
committed
optimize dec2float
1 parent f6685b7 commit b6bdb63

1 file changed

Lines changed: 63 additions & 27 deletions

File tree

source/mir/bignum/internal/dec2float.d

Lines changed: 63 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -140,40 +140,76 @@ T decimalToFloatImpl(T)(ulong coefficient, long exponent)
140140
if (_expect(-ExponentM <= exponent && exponent <= ExponentM, true))
141141
{
142142
auto c = coefficient.Fp!64;
143+
143144
T approx = void;
144-
version (all)
145-
{{
146-
auto z = c.extendedMul!true(_load!wordBits(exponent));
147-
approx = z.opCast!(T, true);
148-
long bitsDiff = (cast(ulong) z.opCast!(Fp!wordBits).coefficient & mask) - half;
149-
uint slop = 3 * (exponent < 0);
150-
if (_expect(approx > T.min_normal && (bitsDiff < 0 ? -bitsDiff : bitsDiff) > slop, true))
151-
return approx;
152-
}}
153-
static if (T.mant_dig < 64)
154-
{{
155-
auto z = c.extendedMul!true(_load!128(exponent));
156-
approx = z.opCast!(T, true);
157-
auto bitsDiff = (z.opCast!(Fp!128).coefficient & bigMask) - bigHalf;
158-
if (bitsDiff.signBit)
159-
bitsDiff = UInt!128.init - bitsDiff;
160-
uint slop = 3 * (exponent < 0);
161-
if (_expect(approx > T.min_normal && bitsDiff > slop, true))
162-
return approx;
163-
}}
164-
165-
if (0 <= exponent)
166-
{
167-
if (exponent <= 55) // exact exponent
168-
return approx;
169-
}
170-
else
145+
146+
if (exponent < 0)
171147
{
148+
version (all)
149+
{{
150+
auto z = c.extendedMul!true(_load!wordBits(exponent));
151+
approx = z.opCast!(T, true);
152+
long bitsDiff = (cast(ulong) z.opCast!(Fp!wordBits).coefficient & mask) - half;
153+
uint slop = 3;
154+
if (_expect(approx > T.min_normal && (bitsDiff < 0 ? -bitsDiff : bitsDiff) > slop, true))
155+
return approx;
156+
}}
157+
172158
if (-exponent <= MaxFpPow5!T)
173159
{
174160
auto e = _load!wordBits(-exponent);
175161
return coefficient / e.opCast!(T, true);
176162
}
163+
164+
static if (T.mant_dig < 64)
165+
{{
166+
auto z = c.extendedMul!true(_load!128(exponent));
167+
approx = z.opCast!(T, true);
168+
auto bitsDiff = (z.opCast!(Fp!128).coefficient & bigMask) - bigHalf;
169+
if (bitsDiff.signBit)
170+
bitsDiff = UInt!128.init - bitsDiff;
171+
uint slop = 3;
172+
if (_expect(approx > T.min_normal && bitsDiff > slop, true))
173+
return approx;
174+
}}
175+
176+
}
177+
else
178+
{
179+
version (all)
180+
{{
181+
auto z = c.extendedMul!true(_load!wordBits(exponent));
182+
approx = z.opCast!(T, true);
183+
184+
if (exponent <= 27) // exact exponent
185+
{
186+
return approx;
187+
}
188+
189+
long bitsDiff = (cast(ulong) z.opCast!(Fp!wordBits).coefficient & mask) - half;
190+
uint slop;
191+
if (_expect(approx > T.min_normal && (bitsDiff < 0 ? -bitsDiff : bitsDiff) > slop, true))
192+
return approx;
193+
}}
194+
195+
static if (T.mant_dig < 64)
196+
{{
197+
auto z = c.extendedMul!true(_load!128(exponent));
198+
approx = z.opCast!(T, true);
199+
200+
if (exponent <= 55) // exact exponent
201+
{
202+
return approx;
203+
}
204+
205+
auto bitsDiff = (z.opCast!(Fp!128).coefficient & bigMask) - bigHalf;
206+
if (bitsDiff.signBit)
207+
bitsDiff = UInt!128.init - bitsDiff;
208+
uint slop;
209+
if (_expect(approx > T.min_normal && bitsDiff > slop, true))
210+
return approx;
211+
}}
212+
177213
}
178214
}
179215
size_t[ulong.sizeof / size_t.sizeof] coefficients;

0 commit comments

Comments
 (0)