Golang 的精度问题 big.Float
Precision issue of Golang big.Float
我遇到了一些有趣的 Golang big.Float 计算问题。
问题是
10001000100010001000100010001000100010001000100015.5533 / 10000000000000000000
= 10001000100010001000100010001000.1000100010001000155533
However, big.Float gave "10001000100010001000100010001000.10001000100010001555329999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999997"
代码:
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))
结果:
Percision: 1024
Quotient: 10001000100010001000100010001000.10001000100010001555329999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999997
更令人困惑的是,如果我设置 prec = 512,一个更小的精度,它却产生了正确的结果。
Percision: 512
Quotient: 10001000100010001000100010001000.1000100010001000155533
有谁知道我的代码有什么问题或如何配置 big.Float 以获得预期结果?
感谢大家!
来自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.
并且 SetPrec 设置尾数的位宽而不是一些小数精度。
与 float64s 一样,并非每个十进制数都可以在 big.Float 中精确表示,您的代码显示了这一点。 prec=512 你看到你期望看到的是由于不同的舍入和打印。
经验法则:big.Floats 表现得像 "normal" 浮点数,但有其所有缺点(这里不是每个小数都可以表示)但可能显示较少的舍入错误。
我遇到了一些有趣的 Golang big.Float 计算问题。
问题是
10001000100010001000100010001000100010001000100015.5533 / 10000000000000000000
= 10001000100010001000100010001000.1000100010001000155533
However, big.Float gave "10001000100010001000100010001000.10001000100010001555329999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999997"
代码:
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))
结果:
Percision: 1024
Quotient: 10001000100010001000100010001000.10001000100010001555329999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999997
更令人困惑的是,如果我设置 prec = 512,一个更小的精度,它却产生了正确的结果。
Percision: 512
Quotient: 10001000100010001000100010001000.1000100010001000155533
有谁知道我的代码有什么问题或如何配置 big.Float 以获得预期结果?
感谢大家!
来自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.
并且 SetPrec 设置尾数的位宽而不是一些小数精度。
与 float64s 一样,并非每个十进制数都可以在 big.Float 中精确表示,您的代码显示了这一点。 prec=512 你看到你期望看到的是由于不同的舍入和打印。
经验法则:big.Floats 表现得像 "normal" 浮点数,但有其所有缺点(这里不是每个小数都可以表示)但可能显示较少的舍入错误。