首頁 >後端開發 >Golang >在 Golang 和其他程式語言中處理貨幣

在 Golang 和其他程式語言中處理貨幣

PHPz
PHPz原創
2024-07-18 01:21:31771瀏覽

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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn