首页 > 后端开发 > Golang > 正文

在 Golang 和其他编程语言中处理货币

PHPz
发布: 2024-07-18 01:21:31
原创
746 人浏览过

Handling Currency In Golang And Other Programming Language

用编程语言处理货币是软件开发的一个关键方面,特别是对于处理金融交易、电子商务、银行和会计系统的应用程序。货币价值的准确表示和操纵对于避免可能导致重大财务差异的错误至关重要。

本文将通过 Go 语言的示例探讨处理货币的最佳实践。

精度和准确度

处理货币时最关心的问题之一是准确性。与可能引入舍入误差的浮点数不同,货币值需要精确的表示。

考虑以下代码

package main

import "fmt"

func main() {

    var a float64 = 1.1
    var b float64 = 1.2
    var c float64 = 1.3
    fmt.Println(a + b + c)

}

登录后复制

上面的代码将打印

3.5999999999999996
登录后复制

由于计算机的内存有限,大多数编程语言(包括 Go)都使用 32 或 64 位存储基于 IEEE-754 标准的浮点数,即使使用 64 位精度也不可能存储无限数量的数字,这意味着这些数字在某些时候会四舍五入,这使得它们本质上不精确,并且执行的计算越多,它们就越不精确。

有很多方法可以解决这个问题,例如使用第 3 方库或您使用的编程语言具有本机支持。 在 Go 中,有几个库,包括:

  • shopspring/十进制
  • ericlagergren/十进制
  • alpacahq/alpacadecimal
  • govalues/decimal

感谢 kennfatt 策划了这个图书馆列表

选择库

选择正确的库来处理货币编程需要考虑几个因素。这是一个指南,可帮助您选择适合您需求的十进制库

1. 准确度和精密度

确保库支持精度和准确性满足您的要求。如果处理非常大的数字或非常精确的计算,请寻找任意精度的功能。

2. 易于使用

图书馆应该有清晰、全面的文档。它应该很容易与您现有的代码库和工作流程集成。

3. 性能

考虑性能影响,尤其是当您执行大量计算或在高频交易环境中操作时。

4. 特点

确保功能满足您的需求,从舍入、加法、减法、乘法、除法等基本算术到更复杂的数学运算。

5. 社区和支持

一个拥有良好支持和活跃社区的库对于获得帮助和找到问题的解决方案至关重要。 寻找积极维护和更新的库。

使用第 3 方

本文将使用第三方库 govalues/decimal 作为代码示例,因为文档简单易读,适合代码演示的需要

package main

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

func main() {

    a, _ := decimal.Parse("1.1")
    b, _ := decimal.Parse("1.2")
    c, _ := decimal.Parse("1.3")

    a, _ = a.Add(b)
    a, _ = a.Add(c)
    fmt.Println(a.String())

}
登录后复制

上面的代码将打印

3.6
登录后复制

在上面的例子中没有精度损失,但是由于内存有成本并且不是无限的,小数点后的数字仍然有限,控制小数位数很重要,在这个例子中你可以使用decimal.ParseExact()设置大小

存储和检索

存储在数据库中也需要仔细考虑以保持精度和一致性。

使用适当的列类型

大多数关系数据库都有特定的货币值类型,例如 DECIMAL 或 NUMERIC。

避免浮点存储

就像编程一样,避免将货币值作为浮点数存储在数据库中。

例如在 MySQL 中

CREATE TABLE `users` (
    `id` int,
    `balance` decimal(6, 2)
);
登录后复制

go 中完整的 MySQL 演示

package main

import (
    "database/sql"
    _ "github.com/go-sql-driver/mysql"
)

func main() {

    db, err := sql.Open("mysql", "root:root@tcp(127.0.0.1:3306)/test")
    if err != nil {
        panic(err)
    }

    _, err = db.Exec(`
        CREATE TABLE test (
            id int,
            balance_decimal decimal(16, 8),
            balance_float float(16, 8),
            PRIMARY KEY (id)
        );
    `)

    _, err = db.Exec("INSERT INTO test (id, balance_decimal, balance_float) VALUES (1, 1.1, 1.1)")
    _, err = db.Exec(`
        UPDATE test 
            SET 
                balance_decimal = balance_decimal + 1.2 , 
                balance_float   = balance_float + 1.2 
            WHERE id = 1;
    `)
}

登录后复制

上面的代码会产生

id balance_decimal balance_float
1 2.30000000 2.29999995

Data Transfer

Data transfer also requires careful consideration of precision. a correct format is required

For example in JSON format, using type string guaranteed precision across any programing language

package main

import (
    "encoding/json"
    "log"
)

type Data struct {
    Decimal string  `json:"decimal"`
    Float   float64 `json:"float"`
}

func main() {

    payload := []byte(`{"decimal":"999.99999999999999","float":999.99999999999999}`)

    result := Data{}

    _ = json.Unmarshal(payload, &result)

    log.Print("Decimal: ", result.Decimal)
    log.Print("Float: ", result.Float)

}
登录后复制

Above code would print

Decimal: 999.99999999999999
Float: 1000
登录后复制

Conclusion

Handling currency in programming languages requires careful attention to detail to ensure precision, accuracy, and consistency. By using appropriate data types, libraries, and best practices, developers can avoid common pitfalls and ensure their applications handle currency correctly. Proper handling of currency not only prevents financial errors but also enhances user trust and confidence in the application.

There's no single best library for everyone. Each project has different needs. You should think about what's good and bad about each library based on what your project requires.

External Link

  • Full Code Example
  • govalues/decimal Repo
  • shopspring/decimal Repo
  • ericlagergren/decimal Repo
  • alpacahq/alpacadecimal Repo

以上是在 Golang 和其他编程语言中处理货币的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!