Skip to content

Commit 1c3556d

Browse files
committed
Slight improvement for decimal->double conversion
1 parent 1d38279 commit 1c3556d

File tree

1 file changed

+10
-66
lines changed

1 file changed

+10
-66
lines changed

src/libraries/System.Private.CoreLib/src/System/Decimal.DecCalc.cs

Lines changed: 10 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -148,68 +148,6 @@ private ulong Low64
148148
1e80
149149
};
150150

151-
// Fast access for solving for x in: 2^x = 10^(-n) where n is 0-28
152-
private static readonly int[] s_intDecimalScaleToIeeeBase2 = new int[] {
153-
0,
154-
-1,
155-
-2,
156-
-4,
157-
-5,
158-
-7,
159-
-8,
160-
-10,
161-
-11,
162-
-12,
163-
-14,
164-
-15,
165-
-17,
166-
-18,
167-
-20,
168-
-21,
169-
-23,
170-
-24,
171-
-25,
172-
-27,
173-
-28,
174-
-30,
175-
-31,
176-
-33,
177-
-34,
178-
-36,
179-
-37,
180-
-38,
181-
-40
182-
/* 315,
183-
312,
184-
308,
185-
305,
186-
302,
187-
298,
188-
295,
189-
292,
190-
289,
191-
285,
192-
282,
193-
279,
194-
275,
195-
272,
196-
269,
197-
265,
198-
262,
199-
259,
200-
255,
201-
252,
202-
249,
203-
245,
204-
242,
205-
239,
206-
235,
207-
232,
208-
229,
209-
225,
210-
222*/
211-
};
212-
213151
#region Decimal Math Helpers
214152

215153
private static unsafe uint GetExponent(float f)
@@ -1653,11 +1591,17 @@ internal static float VarR4FromDec(in decimal value)
16531591
/// </summary>
16541592
internal static double VarR8FromDec(in decimal value)
16551593
{
1656-
// Value taken via reverse engineering the double that corresponds to 2^64. (oleaut32 has ds2to64 = DEFDS(0, 0, DBLBIAS + 65, 0))
1657-
const double ds2to64 = 1.8446744073709552e+019;
1594+
// Step 1: Isolate integral component as a double
1595+
decimal integral = Truncate(value);
1596+
UInt128 integralMantissa = new UInt128(integral.High, integral.Low64);
1597+
double integralDouble = (double)integralMantissa;
1598+
1599+
// Step 2: Isolate fractional component as a double
1600+
decimal fractional = value - integral;
1601+
UInt128 fractionalMantissa = new UInt128(fractional.High, fractional.Low64);
1602+
double fractionalDouble = (double)fractionalMantissa / s_doublePowers10[fractional.Scale];
16581603

1659-
double dbl = ((double)value.Low64 +
1660-
(double)value.High * ds2to64) / s_doublePowers10[value.Scale];
1604+
double dbl = integralDouble + fractionalDouble;
16611605

16621606
if (decimal.IsNegative(value))
16631607
dbl = -dbl;

0 commit comments

Comments
 (0)