简体   繁体   English

Golang big.Float的精度问题

[英]Precision issue of Golang big.Float

I've met some interesting problem of Golang big.Float calculation. 我遇到了一个有趣的Golang big.Float计算问题。

The Problem is 问题是

10001000100010001000100010001000100010001000100015.5533 / 1000000000000000000 100010001000100010001000100010001000100010001000100015.5533 / 1000000000000000000

= 10001000100010001000100010001000.1000100010001000155533 = 10001000100010001000100010001000.1000100010001000155533533

However, big.Float gave "10001000100010001000100010001000.10001000100010001555329999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999997" 但是,big.Float给出了“ 100010001000100010001000100010001000.10001000100010001555329999999999999999999999999999999999999999999999999999999999999999999999

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. 而且更令人困惑的是,如果我将prec = 512设置为较小的精度,则会产生正确的结果。

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? 是否有人知道我的代码有什么问题或如何配置big.Float以获得预期的结果?

Thanks to all! 谢谢大家!

From go doc math/big.Float : go doc math/big.Float

A nonzero finite Float represents a multi-precision floating point number 非零的有限浮点数表示多精度浮点数

sign × mantissa × 2**exponent 符号×尾数×2 **指数

with 0.5 <= mantissa < 1.0, and MinExp <= exponent <= MaxExp. 0.5 <=尾数<1.0,且MinExp <=指数<= MaxExp。

And SetPrec sets the bitwidth of the mantissa not some decimal precision. SetPrec设置尾数的位宽而不是十进制精度。

Like with float64s not every decimal number can be represented exact in a big.Float and your code shows this. 与float64一样,并不是每个十进制数字都可以用big.Float精确表示。 The fact that you see what you expect to see with prec=512 is due to different rounding and printing. 之所以可以看到prec = 512,是因为舍入和打印不同。

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. 经验法则:big.Float表现得像“ Normal”浮动,但有所有缺点(此处不能表示每个小数部分),但舍入误差较小。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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