Line | Exclusive | Inclusive | Code |
---|---|---|---|
1 | # This file is a part of Julia, but is derived from | ||
2 | # https://github.com/google/double-conversion which has the following license | ||
3 | # | ||
4 | # Copyright 2006-2014, the V8 project authors. All rights reserved. | ||
5 | # Redistribution and use in source and binary forms, with or without | ||
6 | # modification, are permitted provided that the following conditions are | ||
7 | # met: | ||
8 | # | ||
9 | # * Redistributions of source code must retain the above copyright | ||
10 | # notice, this list of conditions and the following disclaimer. | ||
11 | # * Redistributions in binary form must reproduce the above | ||
12 | # copyright notice, this list of conditions and the following | ||
13 | # disclaimer in the documentation and/or other materials provided | ||
14 | # with the distribution. | ||
15 | # * Neither the name of Google Inc. nor the names of its | ||
16 | # contributors may be used to endorse or promote products derived | ||
17 | # from this software without specific prior written permission. | ||
18 | # | ||
19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
23 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
24 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
25 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
26 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
27 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
28 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
29 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | |||
31 | import Base: -, * | ||
32 | |||
33 | struct Float | ||
34 | s::UInt64 | ||
35 | e::Int32 | ||
36 | de::Int32 | ||
37 | end | ||
38 | |||
39 | Float() = Float(0,0,0) | ||
40 | Float(x,y) = Float(x,y,Int32(0)) | ||
41 | Float(d::AbstractFloat) = Float(_significand(d), _exponent(d)) | ||
42 | |||
43 | # Consts | ||
44 | const Float10MSBits = 0xFFC0000000000000 # used normalize(Float) | ||
45 | const FloatSignMask = 0x8000000000000000 # used in normalize(Float) | ||
46 | const FloatSignificandSize = Int32(64) | ||
47 | |||
48 |
1 (2.38%) samples spent in normalize
function normalize(v::Float)
0 (ex.), 1 (100.00%) (incl.) when called from normalizedbound line 122 |
||
49 | f = v.s | ||
50 | e::Int32 = v.e | ||
51 | 1 (2.38%) |
1 (100.00%)
samples spent calling
==
while (f & Float10MSBits) == 0
|
|
52 | f <<= 10 | ||
53 | e -= 10 | ||
54 | end | ||
55 | while (f & FloatSignMask) == 0 | ||
56 | f <<= 1 | ||
57 | e -= 1 | ||
58 | end | ||
59 | return Float(f,e) | ||
60 | end | ||
61 | function normalize(v::Float64) | ||
62 | s = _significand(v); e = _exponent(v) | ||
63 | while (s & HiddenBit(Float64)) == 0 | ||
64 | s <<= UInt64(1) | ||
65 | e -= Int32(1) | ||
66 | end | ||
67 | s <<= UInt64(FloatSignificandSize - SignificandSize(Float64)) | ||
68 | e -= Int32( FloatSignificandSize - SignificandSize(Float64)) | ||
69 | return Float(s, e) | ||
70 | end | ||
71 | |||
72 | # Float128 | ||
73 | #DenormalExponent(::Type{Float128}) = Int32(-ExponentBias(Float128) + 1) | ||
74 | #ExponentMask(::Type{Float128}) = 0x7fff0000000000000000000000000000 | ||
75 | #PhysicalSignificandSize(::Type{Float128}) = Int32(112) | ||
76 | #SignificandSize(::Type{Float128}) = Int32(113) | ||
77 | #ExponentBias(::Type{Float128}) = Int32(0x00003fff + PhysicalSignificandSize(Float128)) | ||
78 | #SignificandMask(::Type{Float128}) = 0x0000ffffffffffffffffffffffffffff | ||
79 | #HiddenBit(::Type{Float128}) = 0x00010000000000000000000000000000 | ||
80 | #uint_t(d::Float128) = reinterpret(UInt128,d) | ||
81 | # Float64 | ||
82 | DenormalExponent(::Type{Float64}) = Int32(-ExponentBias(Float64) + 1) | ||
83 | ExponentMask(::Type{Float64}) = 0x7FF0000000000000 | ||
84 | PhysicalSignificandSize(::Type{Float64}) = Int32(52) | ||
85 | SignificandSize(::Type{Float64}) = Int32(53) | ||
86 | ExponentBias(::Type{Float64}) = Int32(0x3FF + PhysicalSignificandSize(Float64)) | ||
87 | SignificandMask(::Type{Float64}) = 0x000FFFFFFFFFFFFF | ||
88 | HiddenBit(::Type{Float64}) = 0x0010000000000000 | ||
89 | uint_t(d::Float64) = reinterpret(UInt64,d) | ||
90 | # Float32 | ||
91 | DenormalExponent(::Type{Float32}) = Int32(-ExponentBias(Float32) + 1) | ||
92 | ExponentMask(::Type{Float32}) = 0x7F800000 | ||
93 | PhysicalSignificandSize(::Type{Float32}) = Int32(23) | ||
94 | SignificandSize(::Type{Float32}) = Int32(24) | ||
95 | ExponentBias(::Type{Float32}) = Int32(0x7F + PhysicalSignificandSize(Float32)) | ||
96 | SignificandMask(::Type{Float32}) = 0x007FFFFF | ||
97 | HiddenBit(::Type{Float32}) = 0x00800000 | ||
98 | uint_t(d::Float32) = reinterpret(UInt32,d) | ||
99 | # Float16 | ||
100 | DenormalExponent(::Type{Float16}) = Int32(-ExponentBias(Float16) + 1) | ||
101 | ExponentMask(::Type{Float16}) = 0x7c00 | ||
102 | PhysicalSignificandSize(::Type{Float16}) = Int32(10) | ||
103 | SignificandSize(::Type{Float16}) = Int32(11) | ||
104 | ExponentBias(::Type{Float16}) = Int32(0x000f + PhysicalSignificandSize(Float16)) | ||
105 | SignificandMask(::Type{Float16}) = 0x03ff | ||
106 | HiddenBit(::Type{Float16}) = 0x0400 | ||
107 | uint_t(d::Float16) = reinterpret(UInt16,d) | ||
108 | |||
109 | function _exponent(d::T) where T<:AbstractFloat | ||
110 | isdenormal(d) && return DenormalExponent(T) | ||
111 | biased_e::Int32 = Int32((uint_t(d) & ExponentMask(T)) >> PhysicalSignificandSize(T)) | ||
112 | return Int32(biased_e - ExponentBias(T)) | ||
113 | end | ||
114 | function _significand(d::T) where T<:AbstractFloat | ||
115 | s = uint_t(d) & SignificandMask(T) | ||
116 | return !isdenormal(d) ? s + HiddenBit(T) : s | ||
117 | end | ||
118 | isdenormal(d::T) where {T<:AbstractFloat} = (uint_t(d) & ExponentMask(T)) == 0 | ||
119 | |||
120 |
1 (2.38%) samples spent in normalizedbound
function normalizedbound(f::AbstractFloat)
0 (ex.), 1 (100.00%) (incl.) when called from fastshortest line 107 |
||
121 | v = Float(_significand(f),_exponent(f)) | ||
122 | 1 (2.38%) |
1 (100.00%)
samples spent calling
normalize
m_plus = normalize(Float((v.s << 1) + 1, v.e - 1))
|
|
123 | if lowerboundaryiscloser(f) | ||
124 | m_minus = Float((v.s << 2) - 1, v.e - 2) | ||
125 | else | ||
126 | m_minus = Float((v.s << 1) - 1, v.e - 1) | ||
127 | end | ||
128 | return Float(m_minus.s << (m_minus.e - m_plus.e), m_plus.e), m_plus | ||
129 | end | ||
130 | function lowerboundaryiscloser(f::T) where T<:AbstractFloat | ||
131 | physical_significand_is_zero = (uint_t(f) & SignificandMask(T)) == 0 | ||
132 | return physical_significand_is_zero && (_exponent(f) != DenormalExponent(T)) | ||
133 | end | ||
134 | |||
135 | (-)(a::Float,b::Float) = Float(a.s - b.s,a.e,a.de) | ||
136 | |||
137 | const FloatM32 = 0xFFFFFFFF | ||
138 | |||
139 | function (*)(this::Float,other::Float) | ||
140 | a::UInt64 = this.s >> 32 | ||
141 | b::UInt64 = this.s & FloatM32 | ||
142 | c::UInt64 = other.s >> 32 | ||
143 | d::UInt64 = other.s & FloatM32 | ||
144 | ac::UInt64 = a * c | ||
145 | bc::UInt64 = b * c | ||
146 | ad::UInt64 = a * d | ||
147 | bd::UInt64 = b * d | ||
148 | tmp::UInt64 = (bd >> 32) + (ad & FloatM32) + (bc & FloatM32) | ||
149 | # By adding 1U << 31 to tmp we round the final result. | ||
150 | # Halfway cases will be round up. | ||
151 | tmp += UInt64(1) << 31 | ||
152 | result_f::UInt64 = ac + (ad >> 32) + (bc >> 32) + (tmp >> 32) | ||
153 | return Float(result_f,this.e + other.e + 64,this.de) | ||
154 | end | ||
155 | |||
156 | const CachedPowers = Float[ | ||
157 | Float(0xfa8fd5a0081c0288, -1220, -348), | ||
158 | Float(0xbaaee17fa23ebf76, -1193, -340), | ||
159 | Float(0x8b16fb203055ac76, -1166, -332), | ||
160 | Float(0xcf42894a5dce35ea, -1140, -324), | ||
161 | Float(0x9a6bb0aa55653b2d, -1113, -316), | ||
162 | Float(0xe61acf033d1a45df, -1087, -308), | ||
163 | Float(0xab70fe17c79ac6ca, -1060, -300), | ||
164 | Float(0xff77b1fcbebcdc4f, -1034, -292), | ||
165 | Float(0xbe5691ef416bd60c, -1007, -284), | ||
166 | Float(0x8dd01fad907ffc3c, -980, -276), | ||
167 | Float(0xd3515c2831559a83, -954, -268), | ||
168 | Float(0x9d71ac8fada6c9b5, -927, -260), | ||
169 | Float(0xea9c227723ee8bcb, -901, -252), | ||
170 | Float(0xaecc49914078536d, -874, -244), | ||
171 | Float(0x823c12795db6ce57, -847, -236), | ||
172 | Float(0xc21094364dfb5637, -821, -228), | ||
173 | Float(0x9096ea6f3848984f, -794, -220), | ||
174 | Float(0xd77485cb25823ac7, -768, -212), | ||
175 | Float(0xa086cfcd97bf97f4, -741, -204), | ||
176 | Float(0xef340a98172aace5, -715, -196), | ||
177 | Float(0xb23867fb2a35b28e, -688, -188), | ||
178 | Float(0x84c8d4dfd2c63f3b, -661, -180), | ||
179 | Float(0xc5dd44271ad3cdba, -635, -172), | ||
180 | Float(0x936b9fcebb25c996, -608, -164), | ||
181 | Float(0xdbac6c247d62a584, -582, -156), | ||
182 | Float(0xa3ab66580d5fdaf6, -555, -148), | ||
183 | Float(0xf3e2f893dec3f126, -529, -140), | ||
184 | Float(0xb5b5ada8aaff80b8, -502, -132), | ||
185 | Float(0x87625f056c7c4a8b, -475, -124), | ||
186 | Float(0xc9bcff6034c13053, -449, -116), | ||
187 | Float(0x964e858c91ba2655, -422, -108), | ||
188 | Float(0xdff9772470297ebd, -396, -100), | ||
189 | Float(0xa6dfbd9fb8e5b88f, -369, -92), | ||
190 | Float(0xf8a95fcf88747d94, -343, -84), | ||
191 | Float(0xb94470938fa89bcf, -316, -76), | ||
192 | Float(0x8a08f0f8bf0f156b, -289, -68), | ||
193 | Float(0xcdb02555653131b6, -263, -60), | ||
194 | Float(0x993fe2c6d07b7fac, -236, -52), | ||
195 | Float(0xe45c10c42a2b3b06, -210, -44), | ||
196 | Float(0xaa242499697392d3, -183, -36), | ||
197 | Float(0xfd87b5f28300ca0e, -157, -28), | ||
198 | Float(0xbce5086492111aeb, -130, -20), | ||
199 | Float(0x8cbccc096f5088cc, -103, -12), | ||
200 | Float(0xd1b71758e219652c, -77, -4), | ||
201 | Float(0x9c40000000000000, -50, 4), | ||
202 | Float(0xe8d4a51000000000, -24, 12), | ||
203 | Float(0xad78ebc5ac620000, 3, 20), | ||
204 | Float(0x813f3978f8940984, 30, 28), | ||
205 | Float(0xc097ce7bc90715b3, 56, 36), | ||
206 | Float(0x8f7e32ce7bea5c70, 83, 44), | ||
207 | Float(0xd5d238a4abe98068, 109, 52), | ||
208 | Float(0x9f4f2726179a2245, 136, 60), | ||
209 | Float(0xed63a231d4c4fb27, 162, 68), | ||
210 | Float(0xb0de65388cc8ada8, 189, 76), | ||
211 | Float(0x83c7088e1aab65db, 216, 84), | ||
212 | Float(0xc45d1df942711d9a, 242, 92), | ||
213 | Float(0x924d692ca61be758, 269, 100), | ||
214 | Float(0xda01ee641a708dea, 295, 108), | ||
215 | Float(0xa26da3999aef774a, 322, 116), | ||
216 | Float(0xf209787bb47d6b85, 348, 124), | ||
217 | Float(0xb454e4a179dd1877, 375, 132), | ||
218 | Float(0x865b86925b9bc5c2, 402, 140), | ||
219 | Float(0xc83553c5c8965d3d, 428, 148), | ||
220 | Float(0x952ab45cfa97a0b3, 455, 156), | ||
221 | Float(0xde469fbd99a05fe3, 481, 164), | ||
222 | Float(0xa59bc234db398c25, 508, 172), | ||
223 | Float(0xf6c69a72a3989f5c, 534, 180), | ||
224 | Float(0xb7dcbf5354e9bece, 561, 188), | ||
225 | Float(0x88fcf317f22241e2, 588, 196), | ||
226 | Float(0xcc20ce9bd35c78a5, 614, 204), | ||
227 | Float(0x98165af37b2153df, 641, 212), | ||
228 | Float(0xe2a0b5dc971f303a, 667, 220), | ||
229 | Float(0xa8d9d1535ce3b396, 694, 228), | ||
230 | Float(0xfb9b7cd9a4a7443c, 720, 236), | ||
231 | Float(0xbb764c4ca7a44410, 747, 244), | ||
232 | Float(0x8bab8eefb6409c1a, 774, 252), | ||
233 | Float(0xd01fef10a657842c, 800, 260), | ||
234 | Float(0x9b10a4e5e9913129, 827, 268), | ||
235 | Float(0xe7109bfba19c0c9d, 853, 276), | ||
236 | Float(0xac2820d9623bf429, 880, 284), | ||
237 | Float(0x80444b5e7aa7cf85, 907, 292), | ||
238 | Float(0xbf21e44003acdd2d, 933, 300), | ||
239 | Float(0x8e679c2f5e44ff8f, 960, 308), | ||
240 | Float(0xd433179d9c8cb841, 986, 316), | ||
241 | Float(0x9e19db92b4e31ba9, 1013, 324), | ||
242 | Float(0xeb96bf6ebadf77d9, 1039, 332), | ||
243 | Float(0xaf87023b9bf0ee6b, 1066, 340)] | ||
244 | |||
245 | const CachedPowersLength = length(CachedPowers) | ||
246 | const CachedPowersOffset = 348 # -1 * the first decimal_exponent. | ||
247 | const D_1_LOG2_10 = 0.30102999566398114 # 1 / lg(10) | ||
248 | # Difference between the decimal exponents in the table above. | ||
249 | const DecimalExponentDistance = 8 | ||
250 | const MinDecimalExponent = -348 | ||
251 | const MaxDecimalExponent = 340 | ||
252 | |||
253 |
1 (2.38%) samples spent in binexp_cache
function binexp_cache(min_exponent,max_exponent)
0 (ex.), 1 (100.00%) (incl.) when called from fastshortest line 110 |
||
254 | 1 (2.38%) |
1 (100.00%)
samples spent calling
+
k = ceil(Integer,(min_exponent+63)*D_1_LOG2_10)
|
|
255 | index = div(CachedPowersOffset+k-1,DecimalExponentDistance) + 1 | ||
256 | cp = CachedPowers[index+1] | ||
257 | return cp | ||
258 | end |