溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

go語言中的decimal怎么使用

發(fā)布時間:2023-03-07 16:22:38 來源:億速云 閱讀:139 作者:iii 欄目:開發(fā)技術

這篇文章主要介紹了go語言中的decimal怎么使用的相關知識,內(nèi)容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇go語言中的decimal怎么使用文章都會有所收獲,下面我們一起來看看吧。

    decimal是為了解決Golang中浮點數(shù)計算時精度丟失問題而生的一個庫,使用decimal庫我們可以避免在go中使用浮點數(shù)出現(xiàn)精度丟失的問題。

    1. 精度丟失的case

    func TestFloat(t *testing.T) {
        a := 1100.1
        b := a * 100
        fmt.Println(b) // should be: 110010 output: 110009.99999999999
    }

    上面的精度就發(fā)生了丟失,浮點數(shù)的位數(shù)雖然我們看到的是1100.1,但對于浮點數(shù)的計算而言卻是無限接近于1,但與1不等。

    當我們需要對float的數(shù)據(jù)進行計算的時候,我們可以使用第三方的decimal包來解決這個問題。

    2. decimal的應用場景

    decimal的應用場景主要出現(xiàn)在對float浮點數(shù)進行加減乘除操作的時候,尤其是對于銀行金融一塊的業(yè)務,如果精度丟失,一筆交易上面的損失可以忽略不計,但當交易的規(guī)模達到幾千萬或者億甚至幾十億的時候,這個時候的損失就會大的嚇人了。

    3. 使用decimal

    使用decimal第一步是引入這個包,decimal,在官方的描述中,這個包的功能描述如下:

    Arbitrary-precision fixed-point decimal numbers in go.

    Note: Decimal library can “only” represent numbers with a maximum of 2^31 digits after the decimal point.

    go中任意精度定點的十進制數(shù)

    注意:十進制庫"只能"表示小數(shù)點后最多2^31位的數(shù)字。

    小數(shù)點后2^31位數(shù)字,對于絕大多數(shù)的項目精度要求是足夠的,簡而言之,decimal可以解決我們絕大多數(shù)的浮點數(shù)精度計算場景。

    對于上面精度丟失的case,當我們引入decimal包之后,我們可以得到正確的結(jié)果。

    func TestDecimalOne(t *testing.T){
        a := 1100.1
        b := 100
        d := decimal.NewFromFloat(a)
        result := d.Mul(decimal.NewFromInt(int64(b)))
        fmt.Println(result) // should be: 110010, output: 110010
    }

    計算結(jié)果的精度沒有丟失,計算結(jié)果正確。

    4. decimal其他實用的場景

    使用decimal的時候,切記浮點數(shù)計算所有數(shù)據(jù)的初始化必須通過decimal進行,否則還是會導致精度的丟失,為什么這么說呢,看看下面的例子你就明白了。

    import (
        "fmt"
        "github.com/shopspring/decimal"
        "testing"
    )
    
    func TestDecimal(t *testing.T) {
        x := 0.28
        // this will cause the multi result has error
        // output should be 28, but actually 28.000000000000004(error)
        errorMul := decimal.NewFromFloat(x * 100).String()
    }

    上面的case就是因為100沒有使用decimal進行初始化導致最后計算的精度被擴大了。正確的處理方式如下:

    import (
        "fmt"
        "github.com/shopspring/decimal"
        "testing"
    )
    
    func TestDecimal(t *testing.T) {
        x := 0.28
        // the correct operate number multi is use the decimal Mul method.
        correctMul := decimal.NewFromFloat(x).Mul(decimal.NewFromInt(100)).String()
        fmt.Println(correctMul) // output: 28
    }

    4.1 獲取結(jié)果的整數(shù)部分

    使用IntPart可以獲取到浮點數(shù)計算結(jié)果的整數(shù)部分。

    func TestDecimalTwo(t *testing.T){
        a := 0.01234
        b := 100
        // 0.01234 * 100 = 1.234, int part=1, output=1
        fmt.Println(decimal.NewFromFloat(a).Mul(decimal.NewFromInt(int64(b))).IntPart())
    }

    4.2 小數(shù)點后填充

    使用IntPart可以對計算后的數(shù)據(jù)進行小數(shù)點位數(shù)的補零填充。

    func TestDecimalThree(t *testing.T){
        a := 0.012
        b := 100
        x := decimal.NewFromFloat(a).Mul(decimal.NewFromInt(int64(b)))
        // 小數(shù)點后的位數(shù)填充, 0.012*100=1.2, 填充3位,因為已經(jīng)有一位了,填充兩個0, 1.200
        fmt.Println(x.StringFixed(3))
    }

    4.3 比較數(shù)字的大小

    浮點數(shù)的比較decimal提供了一些比較有用的函數(shù)方法,這里列舉了一部分。

    import (
        "fmt"
        "github.com/shopspring/decimal"
        "testing"
    )
    
    func TestDecimalFour(t *testing.T) {
        a := decimal.NewFromFloat(-1.11)
        b := decimal.NewFromInt(3)
        c, _ := decimal.NewFromString("2.023")
        // 是否是負數(shù)
        fmt.Println(a.IsNegative())
        // 取絕對值
        fmt.Println(a.Abs())
        // 比較是否相等
        fmt.Println(a.Equal(b))
        // 比較小于
        fmt.Println(a.LessThan(b))
        // 比較小于等于
        fmt.Println(a.LessThanOrEqual(b))
        // 比較大于等于
        fmt.Println(b.GreaterThanOrEqual(a))
        // 是否是0
        fmt.Println(c.IsZero())
    }

    關于“go語言中的decimal怎么使用”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對“go語言中的decimal怎么使用”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業(yè)資訊頻道。

    向AI問一下細節(jié)

    免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

    AI