最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Golang使用Decimal庫避免運算中精度損失詳細步驟

 更新時間:2023年06月15日 15:26:41   作者:eRain  
decimal是為了解決Golang中浮點數(shù)計算時精度丟失問題而生的一個庫,使用decimal庫我們可以避免在go中使用浮點數(shù)出現(xiàn)精度丟失的問題,下面這篇文章主要給大家介紹了關于Golang使用Decimal庫避免運算中精度損失的相關資料,需要的朋友可以參考下

前言

我們在項目中涉及到數(shù)值計算時,如果直接使用golang的運算符,會造成精度的損失,例如:

a := 1136.1
b := a * 100
fmt.Println(b) // 正確結果應該是 113610 但輸出 113609.99999999999

c := 1.7
fmt.Println(a - c) // 正確結果應該是 1134.4 但輸出 1134.3999999999999
fmt.Println(b - c) // 正確結果應該是 113608.3 但輸出 113608.29999999999

那么如何避免這種情況呢?golang中沒有提供對于精度運算相應的包。這里需要用到第三方的decimal包了。

一、Decimal庫是什么?

是一個第三方提供的用于go程序數(shù)值計算時避免精度損失的包,引用官方的描述:

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.

注意這里有個Note:Decimal庫“只能”表示小數(shù)點后最多2^31位的數(shù)字。當然,這對于絕大部分項目來說足夠了。

二、使用步驟

1.引入庫

下載包:

go get github.com/shopspring/decimal

go代碼中引入包:

import "github.com/shopspring/decimal"

2.Decimal庫的使用

使用decimal后,上面例子的代碼就應該這樣寫:

package main

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

func main() {
	a := decimal.NewFromFloat(1136.1)
	b := a.Mul(decimal.NewFromInt(100))
	fmt.Println(b) // 正確輸出 113610

	c := decimal.NewFromFloat(1.7)
	fmt.Println(a.Sub(c)) // 正確輸出 1134.4
	fmt.Println(b.Sub(c)) // 正確輸出 113608.3
}

之后對于各種數(shù)字的計算就會變得得心應手:

package main

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

func main() {
	a := decimal.NewFromFloat(1.52)
	b := decimal.NewFromFloat(0.02)

	// 加減乘除運算
	c := a.Add(b) // 1.52 + 0.02 = 1.54
	d := a.Sub(b) // 1.52 - 0.02 = 1.5
	e := a.Mul(b) // 1.52 * 0.02 = 0.0304
	f := a.Div(b) // 1.52 / 0.02 = 76
	fmt.Println(a, b, c, d, e, f)

	// 對于保留小數(shù)的處理
	pi := decimal.NewFromFloat(3.1415926535897932384626)
	pi1 := pi.Round(3)    // 對pi值四舍五入保留3位小數(shù)
	fmt.Println(pi1)       // 3.142
	pi2 := pi.Truncate(3) // 對pi值保留3位小數(shù)之后直接舍棄
	fmt.Println(pi2)       // 3.141
}

對于數(shù)值變量類型的轉換也游刃有余了:

var a float64
var b = "69.77"
var c int64

d, err := decimal.NewFromString(b)
if err != nil {
	fmt.Println(err.Error())
}

a, _ = d.Float64()
fmt.Println(a) // float64 69.77

c = d.IntPart() // 舍去小數(shù)取整
fmt.Println(c)  // int64 69

b = decimal.NewFromInt(c).String()
fmt.Println(b) // string 69

c = d.Round(0).IntPart() // 不保留小數(shù)四舍五入取整
fmt.Println(c)           // int64 70

這里列出一些常用的方法:

n1 := decimal.NewFromFloat(-1.23)
n2 := decimal.NewFromInt(3)
n3, _ := decimal.NewFromString("0")

n1.Abs()                  // 取絕對值
n1.Equal(n2)              // n1 是否與 n2 相等
n1.LessThan(n2)           // n1 是否小于 n2
n1.LessThanOrEqual(n2)    // n1 是否小于或等于 n2
n1.GreaterThan(n2)        // n1 是否大于 n2
n1.GreaterThanOrEqual(n2) // n1 是否大于或等于 n2
n3.IsZero()               // n3 是否為0

總結

Decimal庫會給我們項目中用到數(shù)值計算時提供極大的便利和安全性。

最后需要注意的一點是,使用Decimal庫的變量數(shù)據類型全部為decimal.Decimal,同樣decimal.Decimal也可以作為聲明變量時的數(shù)據類型使用,所以記得在最后做變量賦值時轉換為需要的數(shù)據類型。

package main

import (
	"fmt"
	"github.com/shopspring/decimal"
	"reflect"
)

func main() {
	n1 := decimal.NewFromFloat(3.14)
	var n2 string
	var n3 float64
	var n4 int64
	var n5 decimal.Decimal

	n2 = n1.String()
	n3, _ = n1.Float64()
	n4 = n1.IntPart()

	fmt.Printf("n1 = %v, type = %v\n", n1, reflect.TypeOf(n1).String())
	// n1 = 3.14, type = decimal.Decimal
	fmt.Printf("n2 = %v, type = %v\n", n2, reflect.TypeOf(n2).String())
	// n2 = 3.14, type = string
	fmt.Printf("n3 = %v, type = %v\n", n3, reflect.TypeOf(n3).String())
	// n3 = 3.14, type = float64
	fmt.Printf("n4 = %v, type = %v\n", n4, reflect.TypeOf(n4).String())
	// n4 = 3, type = int64
	fmt.Printf("n5 = %v, type = %v\n", n5, reflect.TypeOf(n5).String())
	// n5 = 0, type = decimal.Decimal
}

到此這篇關于Golang使用Decimal庫避免運算中精度損失的文章就介紹到這了,更多相關Golang避免運算精度損失內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Go+Kafka實現(xiàn)延遲消息的實現(xiàn)示例

    Go+Kafka實現(xiàn)延遲消息的實現(xiàn)示例

    本文主要介紹了Go+Kafka實現(xiàn)延遲消息的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-07-07
  • Go語言實現(xiàn)超時的三種方法實例

    Go語言實現(xiàn)超時的三種方法實例

    超時在一些業(yè)務場景里非常普遍,下面這篇文章主要給大家介紹了關于Go語言實現(xiàn)超時的三種方法,文中通過實例代碼介紹的非常詳細,對大家學習或者使用Go語言具有一定的參考學習價值,需要的朋友可以參考下
    2022-07-07
  • go語言題解LeetCode453最小操作次數(shù)使數(shù)組元素相等

    go語言題解LeetCode453最小操作次數(shù)使數(shù)組元素相等

    這篇文章主要為大家介紹了go語言題解LeetCode453最小操作次數(shù)使數(shù)組元素相等示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • Go錯誤處理的幾種方式

    Go錯誤處理的幾種方式

    在Go語言中,錯誤處理是一種重要的編程模式,它用于處理可能出現(xiàn)的錯誤或異常情況,本文就來介紹一下Go錯誤處理的幾種方式,感興趣的可以了解一下
    2023-11-11
  • Golang線程池與協(xié)程池的使用

    Golang線程池與協(xié)程池的使用

    在Golang中,線程池和協(xié)程池是非常常見且重要的概念,它們可以提高應用程序的并發(fā)處理能力和性能,減少資源的浪費,本文就來介紹一下Golang線程池與協(xié)程池的使用,感興趣的可以了解一下
    2024-04-04
  • Go?chassis云原生微服務開發(fā)框架應用編程實戰(zhàn)

    Go?chassis云原生微服務開發(fā)框架應用編程實戰(zhàn)

    這篇文章主要為大家介紹了Go?chassis云原生微服務開發(fā)框架應用編程實戰(zhàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • golang中defer的關鍵特性示例詳解

    golang中defer的關鍵特性示例詳解

    defer是golang語言中的關鍵字,用于資源的釋放,會在函數(shù)返回之前進行調用。下面這篇文章主要給大家介紹了關于golang中defer的關鍵特性,文中通過示例代碼介紹的非常詳細,對大家具有一定的參考學習價值,需要的朋友們下面來一起看看吧。
    2017-08-08
  • Go Slice進行參數(shù)傳遞如何實現(xiàn)詳解

    Go Slice進行參數(shù)傳遞如何實現(xiàn)詳解

    這篇文章主要為大家介紹了Go Slice進行參數(shù)傳遞如何實現(xiàn)的過程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • Go語言原子操作及互斥鎖的區(qū)別

    Go語言原子操作及互斥鎖的區(qū)別

    原子操作就是不可中斷的操作,本文主要介紹了Go語言原子操作及互斥鎖的區(qū)別,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • 定位并修復 Go 中的內存泄露問題

    定位并修復 Go 中的內存泄露問題

    Go 是一門帶 GC 的語言,這篇文章回顧了我如何發(fā)現(xiàn)內存泄漏、如何修復它,以及我如何修復 Google 示例 Go 代碼中的類似問題,以及我們如何改進我們的庫以防止將來發(fā)生這種情況,感興趣的朋友一起看看吧
    2021-10-10

最新評論

胶州市| 平陆县| 湖口县| 盐亭县| 丰原市| 从化市| 平湖市| 乃东县| 翼城县| 华蓥市| 济南市| 沙雅县| 四川省| 右玉县| 东平县| 青岛市| 宜兰县| 运城市| 佛学| 沁源县| 合水县| 灵武市| 澜沧| 佛坪县| 翁牛特旗| 娄底市| 绩溪县| 洪泽县| 贵港市| 班玛县| 利津县| 郑州市| 台中市| 武鸣县| 中宁县| 沾化县| 太白县| 乡城县| 合江县| 驻马店市| 灵武市|