golang之浮点数处理库decimal

发布时间 2023-08-07 12:46:05作者: X-Wolf

decimal库包是用来解决float类型对象之间运算不准确的问题的。
所以,如果你想使用decimal库包,你必须先把float类型对象通过decimal.NewFromFloat()函数转成decimal.Decimal类型,然后再计算,最后还得再转成你所需要的类型。

范例:

package main

import "log"

func main() {
    a := 1129.6
    log.Println(a * 100) //输出:112959.99999999999

    var b float64 = 1129.6
    log.Println(b * 100) //输出:112959.99999999999

    m1 := 8.2
    m2 := 3.8
    log.Println(m1 - m2) // 期望是4.4,结果打印出了4.399999999999999
}

// 输出的结果是:
2023/03/16 13:38:24 112959.99999999999
2023/03/16 13:38:24 112959.99999999999
2023/03/16 13:38:24 4.3999999999999995
// 从上面的输出结果看到,数值的精度出现了一定程度的变化,这显然不是我们想要的结果。

 

解决:

由于golang中默认是没有decimal类型的,所以要解决上述的问题,需要使用第三方库包decimal decimal.Decimal是一种数据类型

go get github.com/shopspring/decimal

 

使用:

package main

import (
    "fmt"
    "log"
    "github.com/shopspring/decimal"
)

func main() {
    var v1 = decimal.NewFromFloat(0.1)  // 声明一个decimal.Decimal类型的变量v1
    var v2 = decimal.NewFromFloat(0.2)  // 声明一个decimal.Decimal类型的变量v2
    
    // decimal.Decimal类型变量之间的加减乘除
    // 所得到的结果也是decimal.Decimal类型
    var v3 = v1.Add(v2)  // 0.3
    var v4 = v1.Sub(v2)  // -0.1
    var v5 = v1.Mul(v2)  // 0.02
    var v6 = v1.Div(v2)  // 0.5
    
    // 声明一个decimal.Decimal类型的对象
    var v7 = decimal.NewFromFloat(3.4625)
    var data1 = v7.Round(1)     // 3.5,保留一位小数,四舍五入的方式
    var data2 = v7.Truncate(1)  // 3.4,保留一位小数,直接舍弃,直接截断的方式

    log.Println(v3, v4, v5, v6)
    log.Println(data1, data2)
    
// 输出的结果是
0.3 -0.1 0.02 0.5
3.5 3.4

// 最后别忘了还需要转换成你所需要的数据类型
decimal.NewFromFloat(nums).Round(2).Float64() // 四舍五入保留2位小数,最后再转换为float64类型
}