1 // Copyright 2019 Ulf Adams
2 //
3 // The contents of this file may be used under the terms of the Apache License,
4 // Version 2.0.
5 //
6 // (See accompanying file LICENSE-Apache or copy at
7 // http://www.apache.org/licenses/LICENSE-2.0)
8 //
9 // Alternatively, the contents of this file may be used under the terms of
10 // the Boost Software License, Version 1.0.
11 // (See accompanying file LICENSE-Boost or copy at
12 // https://www.boost.org/LICENSE_1_0.txt)
13 //
14 // Unless required by applicable law or agreed to in writing, this software
15 // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 // KIND, either express or implied.
17
18 #include <stdbool.h>
19 #include <stdint.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <ctype.h>
23
24 #ifdef RYU_DEBUG
25 #include <inttypes.h>
26 #include <stdio.h>
27 #endif
28
29 #include "ryu/common.h"
30 #include "ryu/d2s_intrinsics.h"
31
32 #define DOUBLE_MANTISSA_BITS 52
33 #define DOUBLE_EXPONENT_BITS 11
34 #define DOUBLE_EXPONENT_BIAS 1023
35
36 #if defined(_MSC_VER)
37 #include <intrin.h>
38
floor_log2(const uint64_t value)39 static inline uint32_t floor_log2(const uint64_t value) {
40 long index;
41 return _BitScanReverse64(&index, value) ? index : 64;
42 }
43
44 #else
45
floor_log2(const uint64_t value)46 static inline uint32_t floor_log2(const uint64_t value) {
47 return 63 - __builtin_clzll(value);
48 }
49
50 #endif
51
52 // The max function is already defined on Windows.
max32(int32_t a,int32_t b)53 static inline int32_t max32(int32_t a, int32_t b) {
54 return a < b ? b : a;
55 }
56
int64Bits2Double(uint64_t bits)57 static inline double int64Bits2Double(uint64_t bits) {
58 double f;
59 memcpy(&f, &bits, sizeof(double));
60 return f;
61 }
62
63 double
__atod_engine(uint64_t m10,int e10)64 __atod_engine(uint64_t m10, int e10)
65 {
66 #ifdef RYU_DEBUG
67 printf("m10 = %ld\n", m10);
68 printf("e10 = %d\n", e10);
69 printf("m10 * 10^e10 = %" PRIu64 " * 10^%d\n", m10, e10);
70 #endif
71
72 // Convert to binary float m2 * 2^e2, while retaining information about whether the conversion
73 // was exact (trailingZeros).
74 int32_t e2;
75 uint64_t m2;
76 bool trailingZeros;
77 if (e10 >= 0) {
78 // The length of m * 10^e in bits is:
79 // log2(m10 * 10^e10) = log2(m10) + e10 log2(10) = log2(m10) + e10 + e10 * log2(5)
80 //
81 // We want to compute the DOUBLE_MANTISSA_BITS + 1 top-most bits (+1 for the implicit leading
82 // one in IEEE format). We therefore choose a binary output exponent of
83 // log2(m10 * 10^e10) - (DOUBLE_MANTISSA_BITS + 1).
84 //
85 // We use floor(log2(5^e10)) so that we get at least this many bits; better to
86 // have an additional bit than to not have enough bits.
87 e2 = floor_log2(m10) + e10 + log2pow5(e10) - (DOUBLE_MANTISSA_BITS + 1);
88
89 // We now compute [m10 * 10^e10 / 2^e2] = [m10 * 5^e10 / 2^(e2-e10)].
90 // To that end, we use the DOUBLE_POW5_SPLIT table.
91 int j = e2 - e10 - ceil_log2pow5(e10) + DOUBLE_POW5_BITCOUNT;
92 assert(j >= 0);
93 uint64_t pow5[2];
94 __double_computePow5(e10, pow5);
95 m2 = mulShift64(m10, pow5, j);
96
97 // We also compute if the result is exact, i.e.,
98 // [m10 * 10^e10 / 2^e2] == m10 * 10^e10 / 2^e2.
99 // This can only be the case if 2^e2 divides m10 * 10^e10, which in turn requires that the
100 // largest power of 2 that divides m10 + e10 is greater than e2. If e2 is less than e10, then
101 // the result must be exact. Otherwise we use the existing multipleOfPowerOf2 function.
102 trailingZeros = e2 < e10 || (e2 - e10 < 64 && multipleOfPowerOf2(m10, e2 - e10));
103 } else {
104 e2 = floor_log2(m10) + e10 - ceil_log2pow5(-e10) - (DOUBLE_MANTISSA_BITS + 1);
105 int j = e2 - e10 + ceil_log2pow5(-e10) - 1 + DOUBLE_POW5_INV_BITCOUNT;
106 uint64_t pow5[2];
107 __double_computeInvPow5(-e10, pow5);
108 m2 = mulShift64(m10, pow5, j);
109 trailingZeros = multipleOfPowerOf5(m10, -e10);
110 #ifdef RYU_DEBUG
111 printf("pow5 %016lx_%016lx j %d trailingZeros %d\n", pow5[0], pow5[1], j, trailingZeros);
112 #endif
113 }
114
115 #ifdef RYU_DEBUG
116 printf("m2 * 2^e2 = %" PRIu64 " * 2^%d\n", m2, e2);
117 #endif
118
119 // Compute the final IEEE exponent.
120 uint32_t ieee_e2 = (uint32_t) max32(0, e2 + DOUBLE_EXPONENT_BIAS + floor_log2(m2));
121
122 if (ieee_e2 > 0x7fe) {
123 // Final IEEE exponent is larger than the maximum representable; return +/-Infinity.
124 uint64_t ieee = (0x7ffull << DOUBLE_MANTISSA_BITS);
125 return int64Bits2Double(ieee);
126 }
127
128 // We need to figure out how much we need to shift m2. The tricky part is that we need to take
129 // the final IEEE exponent into account, so we need to reverse the bias and also special-case
130 // the value 0.
131 int32_t shift = (ieee_e2 == 0 ? 1 : ieee_e2) - e2 - DOUBLE_EXPONENT_BIAS - DOUBLE_MANTISSA_BITS;
132 assert(shift >= 0);
133 #ifdef RYU_DEBUG
134 printf("ieee_e2 = %d\n", ieee_e2);
135 printf("shift = %d\n", shift);
136 #endif
137
138 // We need to round up if the exact value is more than 0.5 above the value we computed. That's
139 // equivalent to checking if the last removed bit was 1 and either the value was not just
140 // trailing zeros or the result would otherwise be odd.
141 //
142 // We need to update trailingZeros given that we have the exact output exponent ieee_e2 now.
143 trailingZeros &= (m2 & ((1ull << (shift - 1)) - 1)) == 0;
144 uint64_t lastRemovedBit = (m2 >> (shift - 1)) & 1;
145 bool roundUp = (lastRemovedBit != 0) && (!trailingZeros || (((m2 >> shift) & 1) != 0));
146
147 #ifdef RYU_DEBUG
148 printf("roundUp = %d\n", roundUp);
149 printf("ieee_m2 = %" PRIu64 "\n", (m2 >> shift) + roundUp);
150 #endif
151 uint64_t ieee_m2 = (m2 >> shift) + roundUp;
152 assert(ieee_m2 <= (1ull << (DOUBLE_MANTISSA_BITS + 1)));
153 ieee_m2 &= (1ull << DOUBLE_MANTISSA_BITS) - 1;
154 if (ieee_m2 == 0 && roundUp) {
155 // Due to how the IEEE represents +/-Infinity, we don't need to check for overflow here.
156 ieee_e2++;
157 }
158 uint64_t ieee = (((uint64_t)ieee_e2) << DOUBLE_MANTISSA_BITS) | ieee_m2;
159 return int64Bits2Double(ieee);
160 }
161
162