shopspring/decimal 使用教程

github.com/shopspring/decimal 是一个用于高精度十进制运算的 Go 语言库,特别适合需要避免浮点数精度问题的场景,比如金融计算。以下是对其使用方法的整理:

安装

在你的项目中引入该库:

go get github.com/shopspring/decimal

基本用法

创建 Decimal 实例

  1. 从字符串创建:

    import "github.com/shopspring/decimal"
    
    d, err := decimal.NewFromString("123.456")
    if err != nil {
        panic(err)
    }
    fmt.Println(d) // 输出:123.456
  2. 从整数和浮点数创建:

    d1 := decimal.NewFromInt(42)
    d2 := decimal.NewFromFloat(3.14)
    fmt.Println(d1, d2) // 输出:42 3.14
  3. 从整数部分和小数部分创建:

    d := decimal.New(123456, -3) // 123.456
    fmt.Println(d)

基本运算

  1. 加法:

    d1 := decimal.NewFromInt(10)
    d2 := decimal.NewFromInt(20)
    result := d1.Add(d2)
    fmt.Println(result) // 输出:30
  2. 减法:

    result := d1.Sub(d2)
    fmt.Println(result) // 输出:-10
  3. 乘法:

    result := d1.Mul(d2)
    fmt.Println(result) // 输出:200
  4. 除法:

    result := d2.Div(d1)
    fmt.Println(result) // 输出:2
  5. 求余:

    result := d2.Mod(d1)
    fmt.Println(result) // 输出:0

比较操作

  1. 比较两个 Decimal 值

    比较结果有以下几种:

    • -1:表示第一个值小于第二个值
    • 0:表示两个值相等
    • 1:表示第一个值大于第二个值
    d1 := decimal.NewFromFloat(3.14)
    d2 := decimal.NewFromFloat(2.71)
    
    fmt.Println(d1.Cmp(d2)) // 输出:1 表示 d1 > d2
  2. 检查是否相等:

    fmt.Println(d1.Equals(d2)) // 输出:false
  3. 检查是否大于、小于:

    fmt.Println(d1.GreaterThan(d2)) // 输出:true
    fmt.Println(d1.LessThan(d2))    // 输出:false

精度控制

  1. 四舍五入:

    d := decimal.NewFromFloat(3.14159)
    rounded := d.Round(2)
    fmt.Println(rounded) // 输出:3.14
  2. 设置小数位数:

    truncated := d.Truncate(2)
    fmt.Println(truncated) // 输出:3.14

转换为其他类型

  1. 转换为字符串:

    fmt.Println(d.String()) // 输出:3.14
  2. 转换为浮点数:

    f, exact := d.Float64()
    fmt.Println(f, exact) // 输出:3.14159 true
  3. 转换为整数:

    i := d.IntPart()
    fmt.Println(i) // 输出:3

高级特性

  1. 累积计算:

    sum := decimal.Zero
    for i := 1; i <= 10; i++ {
        sum = sum.Add(decimal.NewFromInt(int64(i)))
    }
    fmt.Println(sum) // 输出:55
  2. JSON 序列化和反序列化:

    type Item struct {
        Price decimal.Decimal `json:"price"`
    }
    
    item := Item{Price: decimal.NewFromFloat(19.99)}
    jsonData, _ := json.Marshal(item)
    fmt.Println(string(jsonData)) // 输出:{"price":"19.99"}
    
    var newItem Item
    json.Unmarshal(jsonData, &newItem)
    fmt.Println(newItem.Price) // 输出:19.99
  3. 科学计数法支持:

    d, _ := decimal.NewFromString("1.23e4")
    fmt.Println(d) // 输出:12300

注意事项

  1. decimal 库避免了浮点数精度问题,但需要注意性能开销。
  2. 对于需要频繁处理高精度计算的场景,可以通过复用 Decimal 实例来提高效率。
  3. 确保正确处理错误,例如 NewFromString 返回的错误。

参考链接

每日更新-免费小火箭账号
不要错过任何机会,探索最新的应用和游戏,就在我们的平台。
立即访问
最后修改:2024 年 12 月 29 日
如果觉得我的文章对你有用,请随意赞赏