目录

golang float 浮点数运算失真解决方案(使用第三方 decimal 包可解决)

问题

在使用 go 语言开发业务需求时,有些场景需要用到小数 float,但是在进行 加减乘除 的运算,发现结果会有一定的精度问题,代码如下:

package main

import (
    "fmt"
)

func main() {
    var a float64 = 0.3
    var b float64 = 0.6
    fmt.Println("a+b=", a+b) // 你以为是 0.9  但是结果是:0.8999999999999999
}

正常结果我们需要的是 0.9 ,而不是 0.8999999999999,所以这个精度是不符合我们的需求的

原因

你观察到的 0.3 + 0.6 = 0.8999999999999999 现象这是因为计算机使用二进制浮点数表示十进制小数时的固有精度问题,并且这不是 Go 语言特有的问题。其他的语言也会存在相似的问题,这是所有使用 IEEE 754 浮点数标准的编程语言都会遇到的情况

解决

使用第三方库 decimal 包可以完美解决 golang 浮点数运算失真

实操代码如下:

package main

import (
    "fmt"

    "github.com/shopspring/decimal"
)

func main() {
    var a float64 = 0.3
    var b float64 = 0.6
    a1 := decimal.NewFromFloat(a)
    b1 := decimal.NewFromFloat(b)
    fmt.Println("a+b=", a1.Add(b1)) //  0.9
}

可以看到输出结果为 0.9 符合我们的需求

注意

  • decimal 包建议只用做浮点数 float 计算,不建议用来实现字符串和浮点数之间转换:比如 decimal.NewFromString(“1”) , 在大量数据计算下性能差 (本地压测可以判断性能)

  • decimal 包提供了很多方法,比如判断字符串是否为正数、负数、零值等,不是很建议使用,在本地压缩中大量数据下性能不佳(还不如直接字符串判断是否有前缀 “-”)

    其他方法建议在使用前进行压力测试,确保性能符合项目标准

版权声明

未经授权,禁止转载本文章。
如需转载请保留原文链接并注明出处。即视为默认获得授权。
未保留原文链接未注明出处或删除链接将视为侵权,必追究法律责任!

本文原文链接: https://fiveyoboy.com/articles/go-pkg-decimal/

备用原文链接: https://blog.fiveyoboy.com/articles/go-pkg-decimal/