I've met some interesting problem of Golang big.Float calculation.
The Problem is
10001000100010001000100010001000100010001000100015.5533 / 1000000000000000000
= 10001000100010001000100010001000.1000100010001000155533
However, big.Float gave "10001000100010001000100010001000.10001000100010001555329999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999997"
The code:
var prec uint = 1024 // 512
dec, _ := new(big.Float).SetPrec(prec).SetString("1000000000000000000")
f, _ := new(big.Float).SetPrec(prec).SetString("10001000100010001000100010001000100010001000100015.5533")
q := f.Quo(f, dec)
fmt.Printf("Percision: %d\n", prec)
fmt.Printf("Quotient: %s\n", q.Text('f', -1))
Result:
Percision: 1024
Quotient: 10001000100010001000100010001000.10001000100010001555329999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999997
And the more confusing part is, if I set prec = 512, a smaller precision, it produced correct result instead.
Percision: 512
Quotient: 10001000100010001000100010001000.1000100010001000155533
Doses any one know what's wrong of my code or how to configure big.Float to get expected result?
Thanks to all!
From go doc math/big.Float
:
A nonzero finite Float represents a multi-precision floating point number
sign × mantissa × 2**exponent
with 0.5 <= mantissa < 1.0, and MinExp <= exponent <= MaxExp.
And SetPrec sets the bitwidth of the mantissa not some decimal precision.
Like with float64s not every decimal number can be represented exact in a big.Float and your code shows this. The fact that you see what you expect to see with prec=512 is due to different rounding and printing.
Rule of thumb: big.Floats behave like "normal" floats with all their shortcomings (here not every decimal fraction can be represented) but may show less rounding errors.