master
李光春 2 years ago
parent 40664f145a
commit cf80d21881

@ -0,0 +1,21 @@
<h1>
<a href="https://www.dtapp.net/">Golang Decimal</a>
</h1>
📦 Golang Decimal
[comment]: <> (go)
[![godoc](https://pkg.go.dev/badge/github.com/dtapps/godecimal?status.svg)](https://pkg.go.dev/github.com/dtapps/godecimal)
[![goproxy.cn](https://goproxy.cn/stats/github.com/dtapps/godecimal/badges/download-count.svg)](https://goproxy.cn/stats/github.com/dtapps/godecimal)
[![goreportcard.com](https://goreportcard.com/badge/github.com/dtapps/godecimal)](https://goreportcard.com/report/github.com/dtapps/godecimal)
[![deps.dev](https://img.shields.io/badge/deps-go-red.svg)](https://deps.dev/go/github.com/dtapps/godecimal)
#### 安装使用
```go
go get -v -u github.com/dtapps/godecimal
import (
"github.com/dtapps/godecimal"
)
```

@ -0,0 +1,15 @@
package godecimal
import (
"math/big"
)
type Decimal struct {
floatValue *big.Float
}
func New() Decimal {
return Decimal{
floatValue: new(big.Float),
}
}

@ -0,0 +1,29 @@
package godecimal
// NewString 从字符串创建
func NewString(s string) Decimal {
d := New()
d.floatValue.SetString(s)
return d
}
// NewFloat 从浮点数创建
func NewFloat(f float64) Decimal {
d := New()
d.floatValue.SetFloat64(f)
return d
}
// NewInt 从整数创建
func NewInt(i int64) Decimal {
d := New()
d.floatValue.SetInt64(i)
return d
}
// NewUint 从无符合整数创建
func NewUint(i uint64) Decimal {
d := New()
d.floatValue.SetUint64(i)
return d
}

@ -0,0 +1,29 @@
package godecimal
// Add 加 (d+d2)
func (d Decimal) Add(d2 Decimal) Decimal {
mul := New()
mul.floatValue.Add(d.floatValue, d2.floatValue)
return mul
}
// Sub 减 (d-d2)
func (d Decimal) Sub(d2 Decimal) Decimal {
mul := New()
mul.floatValue.Sub(d.floatValue, d2.floatValue)
return mul
}
// Mul 乘 (d*d2)
func (d Decimal) Mul(d2 Decimal) Decimal {
mul := New()
mul.floatValue.Mul(d.floatValue, d2.floatValue)
return mul
}
// Quo 除 (d/d2)
func (d Decimal) Quo(d2 Decimal) Decimal {
mul := New()
mul.floatValue.Quo(d.floatValue, d2.floatValue)
return mul
}

@ -0,0 +1,24 @@
package godecimal
import (
"math/big"
)
// String 输出 string
func (d Decimal) String() string {
return d.floatValue.String()
}
// Float64 输出 float64
func (d Decimal) Float64() float64 {
rat, _ := new(big.Rat).SetString(d.String())
f, _ := rat.Float64()
return f
}
// MoneyFloat64 货币 float64
func (d Decimal) MoneyFloat64() float64 {
rat, _ := new(big.Rat).SetString(d.floatValue.Text('f', 2))
f, _ := rat.Float64()
return f
}

@ -0,0 +1,97 @@
package godecimal
import (
"fmt"
"github.com/shopspring/decimal"
"math/big"
"reflect"
"testing"
)
func TestNew(t *testing.T) {
priceString := NewString("100")
t.Log("从字符串创建:", priceString)
priceFloat := NewFloat(0.20)
t.Log("从浮点数创建:", priceFloat)
priceInt := NewInt(300)
t.Log("从整数创建:", priceInt)
priceUint := NewUint(400)
t.Log("从无符合整数创建:", priceUint)
t.Log("加:", priceString.Add(priceFloat), reflect.TypeOf(priceString))
t.Log("减", priceString.Sub(priceFloat), reflect.TypeOf(priceString))
t.Log("乘:", priceString.Mul(priceFloat), reflect.TypeOf(priceString))
t.Log("除:", priceString.Quo(priceFloat), reflect.TypeOf(priceString))
}
// https://www.itranslater.com/qa/details/2582643503239005184
// https://stackoverflow.com/questions/18390266/how-can-we-truncate-float64-type-to-a-particular-precision
func TestOperation(t *testing.T) {
a1 := NewFloat(0.1890)
t.Log("a1", a1)
a2 := NewFloat(0.50)
t.Log("a2", a2)
t.Log("a1+a2", a1.Add(a2), a1.Add(a2).String(), a1.Add(a2).Float64(), reflect.TypeOf(a1.Add(a2).Float64()), a1.Add(a2).MoneyFloat64(), reflect.TypeOf(a1.Add(a2).MoneyFloat64()))
t.Log("a1-a2", a1.Sub(a2), a1.Sub(a2).String(), a1.Sub(a2).Float64(), reflect.TypeOf(a1.Sub(a2).Float64()), a1.Sub(a2).MoneyFloat64(), reflect.TypeOf(a1.Sub(a2).MoneyFloat64()))
t.Log("a1*a2", a1.Mul(a2), a1.Mul(a2).String(), a1.Mul(a2).Float64(), reflect.TypeOf(a1.Mul(a2).Float64()), a1.Mul(a2).MoneyFloat64(), reflect.TypeOf(a1.Mul(a2).MoneyFloat64()))
t.Log("a1/a2", a1.Quo(a2), a1.Quo(a2).String(), a1.Quo(a2).Float64(), reflect.TypeOf(a1.Quo(a2).Float64()), a1.Quo(a2).MoneyFloat64(), reflect.TypeOf(a1.Quo(a2).MoneyFloat64()))
a3 := NewFloat(.035)
t.Log("a3", a3)
a4 := NewFloat(.08875)
t.Log("a4", a4)
t.Log("a3+a4", a3.Add(a4), a3.Add(a4).String(), a3.Add(a4).Float64(), reflect.TypeOf(a3.Add(a4).Float64()), a3.Add(a4).MoneyFloat64(), reflect.TypeOf(a3.Add(a4).MoneyFloat64()))
t.Log("a3-a4", a3.Sub(a4), a3.Sub(a4).String(), a3.Sub(a4).Float64(), reflect.TypeOf(a3.Sub(a4).Float64()), a3.Sub(a4).MoneyFloat64(), reflect.TypeOf(a3.Sub(a4).MoneyFloat64()))
t.Log("a3*a4", a3.Mul(a4), a3.Mul(a4).String(), a3.Mul(a4).Float64(), reflect.TypeOf(a3.Mul(a4).Float64()), a3.Mul(a4).MoneyFloat64(), reflect.TypeOf(a3.Mul(a4).MoneyFloat64()))
t.Log("a3/a4", a3.Quo(a4), a3.Quo(a4).String(), a3.Quo(a4).Float64(), reflect.TypeOf(a3.Quo(a4).Float64()), a3.Quo(a4).MoneyFloat64(), reflect.TypeOf(a3.Quo(a4).MoneyFloat64()))
}
func TestDecimal1(t *testing.T) {
price, err := decimal.NewFromString("136.02")
if err != nil {
panic(err)
}
quantity := decimal.NewFromInt(3)
fee, _ := decimal.NewFromString(".035")
taxRate, _ := decimal.NewFromString(".08875")
subtotal := price.Mul(quantity)
preTax := subtotal.Mul(fee.Add(decimal.NewFromFloat(1)))
total := preTax.Mul(taxRate.Add(decimal.NewFromFloat(1)))
fmt.Println("Subtotal:", subtotal, reflect.TypeOf(subtotal)) // Subtotal: 408.06
fmt.Println("Pre-tax:", preTax, reflect.TypeOf(preTax)) // Pre-tax: 422.3421
fmt.Println("Taxes:", total.Sub(preTax)) // Taxes: 37.482861375
fmt.Println("Total:", total) // Total: 459.824961375
fmt.Println("Tax rate:", total.Sub(preTax).Div(preTax)) // Tax rate: 0.08875
t.Log(total.String())
t.Log(total.Float64())
t.Log(total.Floor())
}
func Test3(t *testing.T) {
var x1, y1 float64 = 10, 3
z1 := x1 / y1
t.Log(x1, y1, z1)
x2, y2 := big.NewFloat(10), big.NewFloat(3)
z2 := new(big.Float).Quo(x2, y2)
t.Log(x2, y2, z2)
}

@ -0,0 +1,21 @@
package godecimal
// Float64Add 加 (f1+f2)
func Float64Add(f1, f2 float64) float64 {
return NewFloat(f1).Add(NewFloat(f2)).Float64()
}
// Float64Sub 减 (f1-f2)
func Float64Sub(f1, f2 float64) float64 {
return NewFloat(f1).Sub(NewFloat(f2)).Float64()
}
// Float64Mul 乘 (f1*f2)
func Float64Mul(f1, f2 float64) float64 {
return NewFloat(f1).Mul(NewFloat(f2)).Float64()
}
// Float64Quo 除 (f1/f2)
func Float64Quo(f1, f2 float64) float64 {
return NewFloat(f1).Quo(NewFloat(f2)).Float64()
}

@ -0,0 +1,13 @@
package godecimal
import (
"reflect"
"testing"
)
func TestCalculation(t *testing.T) {
t.Log("加:", Float64Add(10, 3), reflect.TypeOf(Float64Add(10, 3)))
t.Log("减", Float64Sub(10, 3), reflect.TypeOf(Float64Sub(10, 3)))
t.Log("乘:", Float64Mul(10, 3), reflect.TypeOf(Float64Mul(10, 3)))
t.Log("除:", Float64Quo(10, 3), reflect.TypeOf(Float64Quo(10, 3)))
}

@ -1,5 +1,5 @@
module go.dtapp.net/godecimal
module github.com/dtapps/godecimal
go 1.18
require go.dtapp.net/gostring v1.0.3
require github.com/shopspring/decimal v1.3.1

@ -1,2 +1,2 @@
go.dtapp.net/gostring v1.0.3 h1:KSOq4D77/g5yZN/bqWfZ0kOOaPr/P1240vg03+XdENI=
go.dtapp.net/gostring v1.0.3/go.mod h1:+ggrOvgQDQturi1QGsXEpyRN/ZPoRDaqhMujIk5lrgQ=
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=

@ -1,115 +0,0 @@
package godecimal
import (
"fmt"
"go.dtapp.net/gostring"
"math"
"strconv"
)
// Decimal 四舍五入
func Decimal(value float64) float64 {
value, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", value), 64)
return value
}
// Round 四舍五入
func Round(f float64, n int) float64 {
n10 := math.Pow10(n)
return math.Trunc((f+0.5/n10)*n10) / n10
}
// RoundYInt64 四舍五入
func RoundYInt64(y int64, n int) float64 {
return Round(float64(y/100), n)
}
// RoundYString 四舍五入
func RoundYString(y string, n int) float64 {
return Round(gostring.ToFloat64(y)/100, n)
}
// Multiply 相乘
func Multiply(y, x float64) float64 {
return Round(y*x, 2)
}
// PddCouponAmount 优惠券金额
func PddCouponAmount(y int64) float64 {
return Round(float64(y)/100, 2)
}
// PddCouponProportion 拼多多佣金比率
func PddCouponProportion(y int64) float64 {
return Round(float64(y)/10, 2)
}
// PddGoodsOriginalPrice 拼多多商品原价
func PddGoodsOriginalPrice(y int64) float64 {
return Round(float64(y)/100, 2)
}
// PddGoodsPrice 拼多多商品券后价
func PddGoodsPrice(y, x float64) float64 {
return Round(y-x, 2)
}
// PddCommission 拼多多佣金
func PddCommission(y, x float64) float64 {
return Round((y*x)/100, 2)
}
// TbCouponAmount 淘宝优惠券金额
func TbCouponAmount(y int64) float64 {
return Round(float64(y), 2)
}
// TbCouponProportion 淘宝佣金比率
func TbCouponProportion(y string) float64 {
return Round(gostring.ToFloat64(y)/100, 2)
}
// TbGoodsOriginalPrice 淘宝商品原价
func TbGoodsOriginalPrice(y string) float64 {
return Round(gostring.ToFloat64(y), 2)
}
// TbGoodsPrice 淘宝商品券后价
func TbGoodsPrice(y, x float64) float64 {
return Round(y-x, 2)
}
// TbCommission 淘宝佣金
func TbCommission(y, x float64) float64 {
return Round((y*x)/100, 2)
}
// WmCouponAmount 小商店优惠券金额
func WmCouponAmount(y string) float64 {
return Round(gostring.ToFloat64(y)/100, 2)
}
// WmCouponProportion 小商店佣金比率
func WmCouponProportion(y int64) float64 {
return Round(float64(y)/100, 2)
}
// WmCommission 小商店佣金
func WmCommission(y int64) float64 {
return Round(float64(y)/100, 2)
}
// WmGoodsOriginalPrice 小商店商品原价
func WmGoodsOriginalPrice(y int64) float64 {
return Round(float64(y)/100, 2)
}
// WmGoodsPrice 小商店商品券后价
func WmGoodsPrice(y int64) float64 {
return Round(float64(y)/100, 2)
}
// JdCommission 京东佣金
func JdCommission(y, x float64) float64 {
return Round((y*x)/100, 2)
}

@ -1,16 +0,0 @@
package godecimal
import (
"testing"
)
func TestDecimal(t *testing.T) {
t.Log(Decimal(2.3333))
}
func TestRound(t *testing.T) {
t.Log(Round(2.3333, 1))
t.Log(Round(2.3333, 2))
t.Log(Round(2.3333, 3))
t.Log(Round(2.3333, 4))
}

@ -0,0 +1,38 @@
package godecimal
import "math"
// Abs 取绝对值
func Abs(x float64) float64 {
return math.Abs(x)
}
// Floor 向下取整
func Floor(x float64) float64 {
return math.Floor(x)
}
// Ceil 向上取整
func Ceil(x float64) float64 {
return math.Ceil(x)
}
// Round 就近取整
func Round(x float64) float64 {
return math.Round(x)
}
// RoundPoint 就近取整并保留小数点
func RoundPoint(x float64) float64 {
return math.Round(x*100) / 100
}
// Max 取较大值
func Max(x, y float64) float64 {
return math.Max(x, y)
}
// Min 取较小值
func Min(x, y float64) float64 {
return math.Min(x, y)
}

@ -0,0 +1,26 @@
package godecimal
import "testing"
func TestMath(t *testing.T) {
t.Log(Abs(111))
t.Log(Abs(-111))
t.Log(Floor(3.4))
t.Log(Floor(3.5))
t.Log(Ceil(3.4))
t.Log(Ceil(3.5))
t.Log(Round(3.4))
t.Log(Round(3.5))
t.Log(RoundPoint(3.4))
t.Log(RoundPoint(3.5))
t.Log(RoundPoint(3.14))
t.Log(RoundPoint(3.14159))
t.Log(Max(4, 3))
t.Log(Min(4, 3))
}

@ -1,3 +1,3 @@
package godecimal
const Version = "1.0.0"
const Version = "1.0.1"

Loading…
Cancel
Save