MCPcopy Index your code
hub / github.com/pquerna/ffjson / AssignDecimal

Method AssignDecimal

fflib/v1/extfloat.go:262–330  ·  view source on GitHub ↗

AssignDecimal sets f to an approximate value mantissa*10^exp. It returns true if the value represented by f is guaranteed to be the best approximation of d after being rounded to a float64 or float32 depending on flt.

(mantissa uint64, exp10 int, neg bool, trunc bool, flt *floatInfo)

Source from the content-addressed store, hash-verified

260// best approximation of d after being rounded to a float64 or
261// float32 depending on flt.
262func (f *extFloat) AssignDecimal(mantissa uint64, exp10 int, neg bool, trunc bool, flt *floatInfo) (ok bool) {
263 const uint64digits = 19
264 const errorscale = 8
265 errors := 0 // An upper bound for error, computed in errorscale*ulp.
266 if trunc {
267 // the decimal number was truncated.
268 errors += errorscale / 2
269 }
270
271 f.mant = mantissa
272 f.exp = 0
273 f.neg = neg
274
275 // Multiply by powers of ten.
276 i := (exp10 - firstPowerOfTen) / stepPowerOfTen
277 if exp10 < firstPowerOfTen || i >= len(powersOfTen) {
278 return false
279 }
280 adjExp := (exp10 - firstPowerOfTen) % stepPowerOfTen
281
282 // We multiply by exp%step
283 if adjExp < uint64digits && mantissa < uint64pow10[uint64digits-adjExp] {
284 // We can multiply the mantissa exactly.
285 f.mant *= uint64pow10[adjExp]
286 f.Normalize()
287 } else {
288 f.Normalize()
289 f.Multiply(smallPowersOfTen[adjExp])
290 errors += errorscale / 2
291 }
292
293 // We multiply by 10 to the exp - exp%step.
294 f.Multiply(powersOfTen[i])
295 if errors > 0 {
296 errors += 1
297 }
298 errors += errorscale / 2
299
300 // Normalize
301 shift := f.Normalize()
302 errors <<= shift
303
304 // Now f is a good approximation of the decimal.
305 // Check whether the error is too large: that is, if the mantissa
306 // is perturbated by the error, the resulting float64 will change.
307 // The 64 bits mantissa is 1 + 52 bits for float64 + 11 extra bits.
308 //
309 // In many cases the approximation will be good enough.
310 denormalExp := flt.bias - 63
311 var extrabits uint
312 if f.exp <= denormalExp {
313 // f.mant * 2^f.exp is smaller than 2^(flt.bias+1).
314 extrabits = uint(63 - flt.mantbits + 1 + uint(denormalExp-f.exp))
315 } else {
316 extrabits = uint(63 - flt.mantbits)
317 }
318
319 halfway := uint64(1) << (extrabits - 1)

Callers

nothing calls this directly

Calls 2

NormalizeMethod · 0.95
MultiplyMethod · 0.95

Tested by

no test coverage detected