简体   繁体   中英

Precision issue of Golang big.Float

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM