Golang 浮点数运算 避免精度损失 Decimal包

Golang 小数计算现状:

存在精度损失

d := 1129.6
fmt.Println((d * 100))   //输出:112959.99999999999

var d float64 = 1129.6
fmt.Println((d * 100)) //输出:112959.99999999999

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

解决方案:

Decimal

由于golang中默认没有decimal类型,如果想使用decimal类型需要通过第三方包

go get github.com/shopspring/decimal

decimal使用方式

package main

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

func main() {
	var v1 = decimal.NewFromFloat(0.1)
	var v2 = decimal.NewFromFloat(0.2)

	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

	var v7 = decimal.NewFromFloat(3.4625)
	var data1 = v7.Round(1)     // 3.5 保留一位小数,四舍五入
	var data2 = v7.Truncate(1)  // 3.4 保留一位小数,直接舍弃

	fmt.Println(v3, v4, v5, v6)
	fmt.Println(data1, data2)
}

注意:

运算过程中数据全部变为 decimal.Decimal 格式,在最后计算时需要将其转换成需要的格式

package main

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

func main() {
	var v1 = decimal.NewFromFloat(0.1)
	var v1 = decimal.NewFromFloat(0.1)
	var resp1 float64
	var resp2 string
	resp1, _ = v1.Float64()  // note: 注意这边第二个参数并不是ok,而是是否准确
	resp2 = v1.String()

	fmt.Printf("resp1 = %v, type = %v\n", resp1, reflect.TypeOf(resp1).String())
	// output: resp1 = 0.1, type = float64
	fmt.Printf("resp2 = %v, type = %v\n", resp2, reflect.TypeOf(resp2).String())
	// output: resp2 = 0.1, type = string
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值