@@ -126,53 +126,6 @@ var powersOfTen = [...]extFloat{
126
126
{0xaf87023b9bf0ee6b , 1066 , false }, // 10^340
127
127
}
128
128
129
- // floatBits returns the bits of the float64 that best approximates
130
- // the extFloat passed as receiver. Overflow is set to true if
131
- // the resulting float64 is ±Inf.
132
- func (f * extFloat ) floatBits (flt * floatInfo ) (bits uint64 , overflow bool ) {
133
- f .Normalize ()
134
-
135
- exp := f .exp + 63
136
-
137
- // Exponent too small.
138
- if exp < flt .bias + 1 {
139
- n := flt .bias + 1 - exp
140
- f .mant >>= uint (n )
141
- exp += n
142
- }
143
-
144
- // Extract 1+flt.mantbits bits from the 64-bit mantissa.
145
- mant := f .mant >> (63 - flt .mantbits )
146
- if f .mant & (1 << (62 - flt .mantbits )) != 0 {
147
- // Round up.
148
- mant += 1
149
- }
150
-
151
- // Rounding might have added a bit; shift down.
152
- if mant == 2 << flt .mantbits {
153
- mant >>= 1
154
- exp ++
155
- }
156
-
157
- // Infinities.
158
- if exp - flt .bias >= 1 << flt .expbits - 1 {
159
- // ±Inf
160
- mant = 0
161
- exp = 1 << flt .expbits - 1 + flt .bias
162
- overflow = true
163
- } else if mant & (1 << flt .mantbits ) == 0 {
164
- // Denormalized?
165
- exp = flt .bias
166
- }
167
- // Assemble bits.
168
- bits = mant & (uint64 (1 )<< flt .mantbits - 1 )
169
- bits |= uint64 ((exp - flt .bias )& (1 << flt .expbits - 1 )) << flt .mantbits
170
- if f .neg {
171
- bits |= 1 << (flt .mantbits + flt .expbits )
172
- }
173
- return
174
- }
175
-
176
129
// AssignComputeBounds sets f to the floating point value
177
130
// defined by mant, exp and precision given by flt. It returns
178
131
// lower, upper such that any number in the closed interval
@@ -225,102 +178,6 @@ var uint64pow10 = [...]uint64{
225
178
1e10 , 1e11 , 1e12 , 1e13 , 1e14 , 1e15 , 1e16 , 1e17 , 1e18 , 1e19 ,
226
179
}
227
180
228
- // AssignDecimal sets f to an approximate value mantissa*10^exp. It
229
- // reports whether the value represented by f is guaranteed to be the
230
- // best approximation of d after being rounded to a float64 or
231
- // float32 depending on flt.
232
- func (f * extFloat ) AssignDecimal (mantissa uint64 , exp10 int , neg bool , trunc bool , flt * floatInfo ) (ok bool ) {
233
- const uint64digits = 19
234
-
235
- // Errors (in the "numerical approximation" sense, not the "Go's error
236
- // type" sense) in this function are measured as multiples of 1/8 of a ULP,
237
- // so that "1/2 of a ULP" can be represented in integer arithmetic.
238
- //
239
- // The C++ double-conversion library also uses this 8x scaling factor:
240
- // https://github.com/google/double-conversion/blob/f4cb2384/double-conversion/strtod.cc#L291
241
- // but this Go implementation has a bug, where it forgets to scale other
242
- // calculations (further below in this function) by the same number. The
243
- // C++ implementation does not forget:
244
- // https://github.com/google/double-conversion/blob/f4cb2384/double-conversion/strtod.cc#L366
245
- //
246
- // Scaling the "errors" in the "is mant_extra in the range (halfway ±
247
- // errors)" check, but not scaling the other values, means that we return
248
- // ok=false (and fall back to a slower atof code path) more often than we
249
- // could. This affects performance but not correctness.
250
- //
251
- // Longer term, we could fix the forgot-to-scale bug (and look carefully
252
- // for correctness regressions; https://codereview.appspot.com/5494068
253
- // landed in 2011), or replace this atof algorithm with a faster one (e.g.
254
- // Ryu). Shorter term, this comment will suffice.
255
- const errorscale = 8
256
-
257
- errors := 0 // An upper bound for error, computed in ULP/errorscale.
258
- if trunc {
259
- // the decimal number was truncated.
260
- errors += errorscale / 2
261
- }
262
-
263
- f .mant = mantissa
264
- f .exp = 0
265
- f .neg = neg
266
-
267
- // Multiply by powers of ten.
268
- i := (exp10 - firstPowerOfTen ) / stepPowerOfTen
269
- if exp10 < firstPowerOfTen || i >= len (powersOfTen ) {
270
- return false
271
- }
272
- adjExp := (exp10 - firstPowerOfTen ) % stepPowerOfTen
273
-
274
- // We multiply by exp%step
275
- if adjExp < uint64digits && mantissa < uint64pow10 [uint64digits - adjExp ] {
276
- // We can multiply the mantissa exactly.
277
- f .mant *= uint64pow10 [adjExp ]
278
- f .Normalize ()
279
- } else {
280
- f .Normalize ()
281
- f .Multiply (smallPowersOfTen [adjExp ])
282
- errors += errorscale / 2
283
- }
284
-
285
- // We multiply by 10 to the exp - exp%step.
286
- f .Multiply (powersOfTen [i ])
287
- if errors > 0 {
288
- errors += 1
289
- }
290
- errors += errorscale / 2
291
-
292
- // Normalize
293
- shift := f .Normalize ()
294
- errors <<= shift
295
-
296
- // Now f is a good approximation of the decimal.
297
- // Check whether the error is too large: that is, if the mantissa
298
- // is perturbated by the error, the resulting float64 will change.
299
- // The 64 bits mantissa is 1 + 52 bits for float64 + 11 extra bits.
300
- //
301
- // In many cases the approximation will be good enough.
302
- denormalExp := flt .bias - 63
303
- var extrabits uint
304
- if f .exp <= denormalExp {
305
- // f.mant * 2^f.exp is smaller than 2^(flt.bias+1).
306
- extrabits = 63 - flt .mantbits + 1 + uint (denormalExp - f .exp )
307
- } else {
308
- extrabits = 63 - flt .mantbits
309
- }
310
-
311
- halfway := uint64 (1 ) << (extrabits - 1 )
312
- mant_extra := f .mant & (1 << extrabits - 1 )
313
-
314
- // Do a signed comparison here! If the error estimate could make
315
- // the mantissa round differently for the conversion to double,
316
- // then we can't give a definite answer.
317
- if int64 (halfway )- int64 (errors ) < int64 (mant_extra ) &&
318
- int64 (mant_extra ) < int64 (halfway )+ int64 (errors ) {
319
- return false
320
- }
321
- return true
322
- }
323
-
324
181
// Frexp10 is an analogue of math.Frexp for decimal powers. It scales
325
182
// f by an approximate power of ten 10^-exp, and returns exp10, so
326
183
// that f*10^exp10 has the same value as the old f, up to an ulp,
0 commit comments