精确计算

decimal

package main

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

// imprecise 不精确demo
func imprecise() {
	a := 2.07
	b := 1.0
	c := a - b
	fmt.Printf("c=%v\n", c)
	//c=1.0699999999999998
}

func main() {
	a := "2.07"
	b := "1.0"
	ad, err := decimal.NewFromString(a)
	if err != nil {
		log.Error(err)
	}
	bd, err := decimal.NewFromString(b)
	if err != nil {
		log.Error(err)
	}
	cd := ad.Sub(bd)
	c, _ := cd.Float64()
	fmt.Printf("c=%v\n", c)
}


官方包

// Pct x,y百分比值
func Pct(x, y float64) float64 {
	xb := big.NewFloat(x)
	yb := big.NewFloat(y)
	pct := big.NewFloat(100)

	res, _ := xb.Mul(xb.Quo(xb, yb), pct).Float64()
	res = math.Trunc(res*1e2) * 1e-2
	return res
}

func main() {
	// 有理数
	price := big.NewRat(48, 1) // 48/1
	total := big.NewRat(95, 1) // 95/1
	pct := big.NewRat(100, 1)  // 100/1

	// 注:Rat结构体对应方法,只针对结果,故无论是price.Mul或者total.Mul效果是一样的
	tf, _ := total.Mul(total.Quo(price, total), pct).Float64() // 该表达式等价于-->价格/总价*100
	t := math.Trunc(tf*1e2) * 1e-2                             // 浮点类型保留小数点2位
	fmt.Println(t)

	fmt.Println(Pct(3,78))
}