如何使用逗号和两位小数格式化货币?

huangapple go评论106阅读模式
英文:

How do I format a currency with commas and 2 decimal places?

问题

我正在尝试将一些数字格式化为带有逗号和两位小数的货币形式。我找到了 "github.com/dustin/go-humanize" 来添加逗号,但它不允许指定小数位数。而 fmt.Sprintf 可以进行货币和小数格式化,但不能添加逗号。

以下是代码示例:

import (
    "fmt"
    "github.com/dustin/go-humanize"
)

func main() {
    for _, fl := range []float64{123456.789, 123456.0, 123456.0100} {
        formatted := fmt.Sprintf("$%.2f", fl)
        commaFormatted := humanize.Commaf(formatted)
        fmt.Println(commaFormatted)
    }
}

结果:

$123,456.79
$123,456.00
$123,456.01

这样你就可以得到期望的结果了。

英文:

I am trying to format some numbers as a currency, with commas and 2 decimal places. I've found "github.com/dustin/go-humanize" for the commas but it doesn't allow for specifying the number of decimal places. fmt.Sprintf will do the currency and decimal formatting but not the commas.

for _, fl := range []float64{123456.789, 123456.0, 123456.0100} {
    log.Println(humanize.Commaf(fl))
  }

Results:

123,456.789
123,456
123,456.01

I am expecting:

$123,456.79
$123,456.00
$123,456.01

答案1

得分: 12

这是humanize.FormatFloat()的作用:

// FormatFloat根据以下用户指定的条件,将格式化的数字转换为字符串:
// * 千位分隔符
// * 小数点分隔符
// * 小数精度

在你的情况下:

FormatFloat("#,###.##", afloat)

话虽如此,正如LenW评论的那样,float(在Go中是float64)不适合用于货币。
请参考floating-point-gui.de

使用像go-inf/inf这样的包(以前是go/dec,例如在此货币实现中使用)会更好。

请参考Dec.go

// Dec表示一个带符号的任意精度十进制数。
// 它由一个符号、一个任意精度整数系数值和一个带符号的固定精度指数值组成。
// 符号和系数值一起作为一个带符号的值处理,并称为无标度值。

该类型Dec包括一个Format()方法


自2015年7月以来,您现在可以使用**leekchan/accounting**,由Kyoung-chan Lee (leekchan)提供相同的建议:

> 请不要使用float64来计算货币。在对其执行操作时,浮点数可能会产生误差。
强烈建议使用big.Rat(< Go 1.5)或big.Float(>= Go 1.5)。 (accounting支持float64,但仅供方便使用。)

fmt.Println(ac.FormatMoneyBigFloat(big.NewFloat(123456789.213123))) // "$123,456,789.21"
英文:

That would be what the humanize.FormatFloat() does:

// FormatFloat produces a formatted number as string based on the following user-specified criteria:
// * thousands separator
// * decimal separator
// * decimal precision

In your case:

FormatFloat(&quot;#,###.##&quot;, afloat)

That being said, as commented by LenW, float (in Go, float64) is not a good fit for currency.
See floating-point-gui.de.

Using a package like go-inf/inf (previously go/dec, used for instance in this currency implementation) is better.

See Dec.go:

// A Dec represents a signed arbitrary-precision decimal.
// It is a combination of a sign, an arbitrary-precision integer coefficient
// value, and a signed fixed-precision exponent value.
// The sign and the coefficient value are handled together as a signed value
// and referred to as the unscaled value.

That type Dec does include a Format() method.


Since July 2015, you now have leekchan/accounting from Kyoung-chan Lee (leekchan) with the same advice:

> Please do not use float64 to count money. Floats can have errors when you perform operations on them.
Using big.Rat (< Go 1.5) or big.Float (>= Go 1.5) is highly recommended. (accounting supports float64, but it is just for convenience.)

fmt.Println(ac.FormatMoneyBigFloat(big.NewFloat(123456789.213123))) // &quot;$123,456,789.21&quot;

答案2

得分: 4

这里有一篇关于为什么不应该使用浮点数来表示货币的好的博客文章,链接在这里 - http://engineering.shopspring.com/2015/03/03/decimal/

从他们的例子中,你可以:

d := New(-12345, -3)
println(d.String())

将会得到:

-12.345
英文:

There is a good blog post about why you should never use floats to represent currency here - http://engineering.shopspring.com/2015/03/03/decimal/

From their examples you can :

  d := New(-12345, -3)
  println(d.String())

Will give you :

-12.345

答案3

得分: 0

fmt.Printf("%.2f", 12.3456)

-- 输出结果为 12.34

英文:
fmt.Printf(&quot;%.2f&quot;, 12.3456) 

-- output is 12.34

huangapple
  • 本文由 发表于 2015年7月20日 01:09:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/31503742.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定