3 回答

TA貢獻1825條經驗 獲得超4個贊
永遠,永遠,永遠不要使用浮動貨幣。它是一種不精確的類型,因此您最終不得不四舍五入計算并且最終在這里和那里損失(或獲得)一分錢。您可能認為這沒問題,但您的會計師會告訴您不是。你必須完全準確。
因此,要么使用專門的任意精度十進制類型,要么使用整數并保存一分錢(或一分錢的分數)并適當地顯示它。(就像您如何將日期保存為自 1970 年以來的秒數,但將它們顯示為 dd-mm-yyyy)。
附注。切勿使用浮動貨幣。真的。
聚苯乙烯。不要使用浮動貨幣,永遠不要永遠。

TA貢獻1829條經驗 獲得超6個贊
使用big.Int
代表 1000ths 或 10000ths 一分的值。浮點值不適用于貨幣,尤其是在交易時。如果有人要求您使用浮點值,請嘗試說服他們這是一個壞主意。如果那不起作用,請重新考慮您與他們合作的決定??紤]到您可能會無意中卷入非法活動:https : //en.wikipedia.org/wiki/Salami_slicing
回答您的技術問題:
big.Float
值不是像big.Int
值那樣的任意精度。
SetFloat64
將浮點數的精度設置為一段float64
時間的精度,SetString
根據字符串的內容進行設置。
無論哪種方式,您都希望對 big.Float 值設置的精度進行深思熟慮。您可以使用https://golang.org/pkg/math/big/#Float.SetPrec控制它SetPrec
編輯:
至于陷阱,請考慮基數 10 中的 0.10 在基數 2 中沒有有限表示。由于big.Float
沒有base
字段或與之對應的任何內容,因此它實際上無法準確存儲 0.10。
基本上,只要您使用 Float 作為浮點數而不是整數,您就會留下確切的值。

TA貢獻1853條經驗 獲得超9個贊
您可以使用實現“無限精度”十進制算術的gopkg.in/inf.v0。
對于上面指定的金額,這里是一個例子:
func main() {
var amt inf.Dec
amt.SetUnscaled(1890)
amt.SetScale(2)
fmt.Println(amt.String())
var amt1 inf.Dec
amt1.SetUnscaled(165)
amt1.SetScale(2)
fmt.Println(amt1.String())
var total = inf.NewDec(5, 2)
total = total.Add(&amt, &amt1)
fmt.Println(total.String())
}
它應該按預期打印出 20.55。
添加回答
舉報