Golang big.Float的精度问题

时间:2019-05-14 15:03:15

标签: go math biginteger bigfloat

我遇到了一个有趣的Golang big.Float计算问题。

问题是

10001000100010001000100010001000100010001000100015.5533 / 1000000000000000000

= 10001000100010001000100010001000.1000100010001000155533

但是,大浮点数给了“ 100010001000100010001000100010001000.10001000100010001555329999999999999999999999999999999999999999999999999999999999999

代码:

public class ApiResponse<T extends ApiResponseData> {
    ...
    @SerializedName("data")
    @Expose
    private Data<T> data;
    ...
}

public class Data<T extends ApiResponseData>  {

    @SerializedName("code")
    @Expose
    private String code;

    @SerializedName("time")
    @Expose
    private String time;

    @SerializedName("data")
    @Expose
    private List<T> data;

    ...
}

结果:

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))

更令人困惑的是,如果我将prec = 512设置为较小的精度,则会产生正确的结果。

Percision: 1024
Quotient: 10001000100010001000100010001000.10001000100010001555329999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999997

是否有人知道我的代码有什么问题或如何配置big.Float以获得预期的结果?

谢谢大家!

1 个答案:

答案 0 :(得分:4)

来自go doc math/big.Float

  

一个非零的有限浮点数表示一个多精度浮点数

     

符号×尾数×2 **指数

     

,其中0.5 <=尾数<1.0,而MinExp <=指数<= MaxExp。

然后SetPrec设置尾数的位宽而不是十进制精度。

像float64s一样,不是每个十进制数字都可以用big.Float精确表示。之所以能看到prec = 512的图像,是因为四舍五入和打印不同。

经验法则:大。浮点的行为类似于“普通”浮点,但有所有缺点(此处不能表示每个小数点),但舍入误差较小。