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类型的变量v2IntPart() // 返回整数部分
// 支持从其他数据类型中解析浮点型数据 NewFromString / NewFromFloat32 / NewFromInt() ... // 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类型
// 转换成其他数据类型
Float64() // 浮点型
String() // 字符串
}
项目实战:
// Fen2Yuan 分转元 func Fen2Yuan[K int | uint](price K) (res float64) { d := decimal.New(1, 2) res, _ = decimal.NewFromInt(int64(float64(price))).DivRound(d, 2).Float64() return } // Yuan2Fen 元转分 func Yuan2Fen(price float32) (yuan int64) { p := decimal.NewFromFloat32(price) yuan = p.Mul(decimal.NewFromInt(100)).IntPart() return }
标签:decimal,浮点数,golang,v1,v2,var,Decimal,log From: https://www.cnblogs.com/xingxia/p/golang_decimal.html