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。
添加回答
举报