英文:
How to fmt.Printf an integer with thousands comma
问题
Go的fmt.Printf
支持输出带有千位分隔符的数字吗?
fmt.Printf("%d", 1000)
输出1000
,我可以指定什么格式来输出1,000
呢?
文档似乎没有提到逗号,我在源代码中也没有立即看到任何相关内容。
英文:
Does Go's fmt.Printf
support outputting a number with the thousands comma?
fmt.Printf("%d", 1000)
outputs 1000
, what format can I specify to output 1,000
instead?
The docs don't seem to mention commas, and I couldn't immediately see anything in the source.
答案1
得分: 138
使用golang.org/x/text/message
来使用本地化格式打印任何语言的内容,使用Unicode CLDR:
package main
import (
"golang.org/x/text/language"
"golang.org/x/text/message"
)
func main() {
p := message.NewPrinter(language.English)
p.Printf("%d\n", 1000)
// 输出:
// 1,000
}
英文:
Use golang.org/x/text/message
to print using localized formatting for any language in the Unicode CLDR:
package main
import (
"golang.org/x/text/language"
"golang.org/x/text/message"
)
func main() {
p := message.NewPrinter(language.English)
p.Printf("%d\n", 1000)
// Output:
// 1,000
}
答案2
得分: 58
我写了一个库humanize来处理这个问题,以及其他一些人类表示的问题。
示例结果:
0 -> 0
100 -> 100
1000 -> 1,000
1000000000 -> 1,000,000,000
-100000 -> -100,000
示例用法:
fmt.Printf("你欠我$%s。\n", humanize.Comma(6582491))
英文:
I wrote a library for this as well as a few other human-representation concerns.
Example results:
0 -> 0
100 -> 100
1000 -> 1,000
1000000000 -> 1,000,000,000
-100000 -> -100,000
Example Usage:
fmt.Printf("You owe $%s.\n", humanize.Comma(6582491))
答案3
得分: 32
没有一个 fmt 打印动词支持千位分隔符。
英文:
None of the fmt print verbs support thousands separators.
答案4
得分: 22
**前言:**我在github.com/icza/gox
上发布了这个带有更多自定义功能的实用程序,请参阅fmtx.FormatInt()
。
fmt
包不支持对小数进行分组。
我们需要自己实现一个(或使用现有的)。
代码
这是一个紧凑且非常高效的解决方案(详细解释见下文):
在Go Playground上尝试一下。
func Format(n int64) string {
in := strconv.FormatInt(n, 10)
numOfDigits := len(in)
if n < 0 {
numOfDigits-- // 第一个字符是负号(不是数字)
}
numOfCommas := (numOfDigits - 1) / 3
out := make([]byte, len(in)+numOfCommas)
if n < 0 {
in, out[0] = in[1:], '-'
}
for i, j, k := len(in)-1, len(out)-1, 0; ; i, j = i-1, j-1 {
out[j] = in[i]
if i == 0 {
return string(out)
}
if k++; k == 3 {
j, k = j-1, 0
out[j] = ','
}
}
}
测试代码:
for _, v := range []int64{0, 1, 12, 123, 1234, 123456789} {
fmt.Printf("%10d = %12s\n", v, Format(v))
fmt.Printf("%10d = %12s\n", -v, Format(-v))
}
输出结果:
0 = 0
0 = 0
1 = 1
-1 = -1
12 = 12
-12 = -12
123 = 123
-123 = -123
1234 = 1,234
-1234 = -1,234
123456789 = 123,456,789
-123456789 = -123,456,789
解释:
Format()
函数的基本功能是对数字进行格式化,不进行分组,然后创建一个足够大的字节切片,并在必要时(如果有更多的数字)将数字的每个组的3个数字之后插入逗号(,
)分组符号,同时确保负号被保留。
输出的长度:
基本上是输入的长度加上要插入的分组符号的数量。分组符号的数量为:
numOfCommas = (numOfDigits - 1) / 3
由于输入字符串是一个只包含数字(0..9
)和可选负号(-
)的数字,字符在UTF-8编码中被简单地映射为字节(这是Go在内存中存储字符串的方式)。因此,我们可以简单地使用字节而不是符文进行操作。因此,数字的位数是输入字符串的长度,如果数字是负数,则可选减去1
:
numOfDigits := len(in)
if n < 0 {
numOfDigits-- // 第一个字符是负号(不是数字)
}
因此,分组符号的数量为:
numOfCommas := (numOfDigits - 1) / 3
因此,输出切片将是:
out := make([]byte, len(in)+numOfCommas)
处理负号字符:
如果数字是负数,我们只需切片输入字符串以排除它,并将符号位手动复制到输出中:
if n < 0 {
in, out[0] = in[1:], '-'
}
因此,函数的其余部分不需要知道/关心可选的负号字符。
函数的其余部分是一个for
循环,它只是将数字的字节(数字)从输入字符串复制到输出中,如果有更多数字,则在每个3个数字的组之后插入一个分组符号(,
)。循环向下进行,因此更容易跟踪3个数字的组。完成后(没有更多数字),将输出字节切片作为string
返回。
变体
使用递归处理负数
如果您更关心可读性而不是效率,您可能会喜欢这个版本:
func Format2(n int64) string {
if n < 0 {
return "-" + Format2(-n)
}
in := strconv.FormatInt(n, 10)
numOfCommas := (len(in) - 1) / 3
out := make([]byte, len(in)+numOfCommas)
for i, j, k := len(in)-1, len(out)-1, 0; ; i, j = i-1, j-1 {
out[j] = in[i]
if i == 0 {
return string(out)
}
if k++; k == 3 {
j, k = j-1, 0
out[j] = ','
}
}
}
基本上,这个版本使用递归调用处理负数:如果数字是负数,则使用绝对值(正数)调用自身(递归),并在结果前面添加一个"-"
字符串。
使用append()
切片
这是另一个版本,使用内置的append()
函数和切片操作。在理解上更容易,但性能方面不太好:
func Format3(n int64) string {
if n < 0 {
return "-" + Format3(-n)
}
in := []byte(strconv.FormatInt(n, 10))
var out []byte
if i := len(in) % 3; i != 0 {
if out, in = append(out, in[:i]...), in[i:]; len(in) > 0 {
out = append(out, ',')
}
}
for len(in) > 0 {
if out, in = append(out, in[:3]...), in[3:]; len(in) > 0 {
out = append(out, ',')
}
}
return string(out)
}
第一个if
语句处理第一个可选的、不足3位数字的“不完整”组,如果存在的话,并且随后的for
循环处理剩下的部分,每次迭代复制3个数字并追加逗号(,
)分组符号(如果还有更多数字)。
英文:
Foreword: I released this utility with more customization in github.com/icza/gox
, see fmtx.FormatInt()
.
The fmt
package does not support grouping decimals.
We have to implement one ourselves (or use an existing one).
The Code
Here is a compact and really efficient solution (see explanation after):
Try it on the Go Playground.
func Format(n int64) string {
in := strconv.FormatInt(n, 10)
numOfDigits := len(in)
if n < 0 {
numOfDigits-- // First character is the - sign (not a digit)
}
numOfCommas := (numOfDigits - 1) / 3
out := make([]byte, len(in)+numOfCommas)
if n < 0 {
in, out[0] = in[1:], '-'
}
for i, j, k := len(in)-1, len(out)-1, 0; ; i, j = i-1, j-1 {
out[j] = in[i]
if i == 0 {
return string(out)
}
if k++; k == 3 {
j, k = j-1, 0
out[j] = ','
}
}
}
Testing it:
for _, v := range []int64{0, 1, 12, 123, 1234, 123456789} {
fmt.Printf("%10d = %12s\n", v, Format(v))
fmt.Printf("%10d = %12s\n", -v, Format(-v))
}
Output:
0 = 0
0 = 0
1 = 1
-1 = -1
12 = 12
-12 = -12
123 = 123
-123 = -123
1234 = 1,234
-1234 = -1,234
123456789 = 123,456,789
-123456789 = -123,456,789
Explanation:
Basically what the Format()
function does is it formats the number without grouping, then creates a big enough other slice and copies the digits of the number inserting comma (','
) grouping symbol when necessary (after groups of digits of 3 if there are more digits) meanwhile taking care of the negative sign to be preserved.
The length of the output:
It is basically the length of the input plus the number of grouping signs to be inserted. The number of grouping signs is:
numOfCommas = (numOfDigits - 1) / 3
Since the input string is a number which may only contain digits ('0..9'
) and optionally a negative sign ('-'
), the characters are simply mapped to bytes in a 1-to-1 fashion in UTF-8 encoding (this is how Go stores strings in memory). So we can simply work with bytes instead of runes. So the number of digits is the input string length, optionally minus 1
if the number is negative:
numOfDigits := len(in)
if n < 0 {
numOfDigits-- // First character is the - sign (not a digit)
}
And therefore the number of grouping signs:
numOfCommas := (numOfDigits - 1) / 3
Therefore the output slice will be:
out := make([]byte, len(in)+numOfCommas)
Handling the negative sign character:
If the number is negative, we simply slice the input string to exclude it from processing and we manually copy the sign bit to the output:
if n < 0 {
in, out[0] = in[1:], '-'
}
And therefore the rest of the function does not need to know/care about the optional negative sign character.
The rest of the function is a for
loop which just copies the bytes (digits) of the number from the input string to the output, inserting a grouping sign (','
) after every group of 3 digits if there are more digits. The loop goes downward so it's easier to track the groups of 3 digits. Once done (no more digits), the output byte slice is returned as a string
.
Variations
Handling negative with recursion
If you're less concerned with efficiency and more about readability, you might like this version:
func Format2(n int64) string {
if n < 0 {
return "-" + Format2(-n)
}
in := strconv.FormatInt(n, 10)
numOfCommas := (len(in) - 1) / 3
out := make([]byte, len(in)+numOfCommas)
for i, j, k := len(in)-1, len(out)-1, 0; ; i, j = i-1, j-1 {
out[j] = in[i]
if i == 0 {
return string(out)
}
if k++; k == 3 {
j, k = j-1, 0
out[j] = ','
}
}
}
Basically this handles negative numbers with a recursive call: if the number is negative, calls itself (recursive) with the absolute (positive) value and prepends the result with a "-"
string.
With append()
slices
Here's another version using the builtin append()
function and slice operations. Somewhat easier to understand but not so good performance-wise:
func Format3(n int64) string {
if n < 0 {
return "-" + Format3(-n)
}
in := []byte(strconv.FormatInt(n, 10))
var out []byte
if i := len(in) % 3; i != 0 {
if out, in = append(out, in[:i]...), in[i:]; len(in) > 0 {
out = append(out, ',')
}
}
for len(in) > 0 {
if out, in = append(out, in[:3]...), in[3:]; len(in) > 0 {
out = append(out, ',')
}
}
return string(out)
}
The first if
statement takes care of the first optional, "incomplete" group which is less than 3 digits if exists, and the subsequent for
loop handles the rest, copying 3 digits in each iteration and appending a comma (','
) grouping sign if there are more digits.
答案5
得分: 16
我在Github上发布了一个Go代码片段,用于根据用户指定的千位分隔符、小数点分隔符和小数精度来渲染一个数字(float64或int)。
https://gist.github.com/gorhill/5285193
<pre>
用法:s := RenderFloat(format, n)
format参数告诉如何渲染数字n。
格式字符串的示例,给定n = 12345.6789:
"#,###.##" => "12,345.67"
"#,###." => "12,345"
"#,###" => "12345,678"
"#\u202F###,##" => "12 345,67"
"#.###,###### => 12.345,678900
""(也称为默认格式) => 12,345.67
</pre>
英文:
I published a Go snippet over at Github of a function to render a number (float64 or int) according to user-specified thousand separator, decimal separator and decimal precision.
https://gist.github.com/gorhill/5285193
<pre>
Usage: s := RenderFloat(format, n)
The format parameter tells how to render the number n.
Examples of format strings, given n = 12345.6789:
"#,###.##" => "12,345.67"
"#,###." => "12,345"
"#,###" => "12345,678"
"#\u202F###,##" => "12 345,67"
"#.###,###### => 12.345,678900
"" (aka default format) => 12,345.67
</pre>
答案6
得分: 10
这是一个函数,它接受一个整数和分组分隔符,并返回一个用指定分隔符分隔的字符串。我尝试优化效率,紧密循环中没有字符串连接或模除运算。根据我的分析,在我的Mac上,它比humanize.Commas实现(约680纳秒对1642纳秒)快两倍以上。我是Go的新手,很想看到更快的实现!
用法:s := NumberToString(n int, sep rune)
示例
演示了使用不同的分隔符(',' vs ' '),并通过int值范围进行验证。
s:= NumberToString(12345678, ',')
=> "12,345,678"
s:= NumberToString(12345678, ' ')
=> "12 345 678"
s: = NumberToString(-9223372036854775807, ',')
=> "-9,223,372,036,854,775,807"
函数实现
func NumberToString(n int, sep rune) string {
s := strconv.Itoa(n)
startOffset := 0
var buff bytes.Buffer
if n < 0 {
startOffset = 1
buff.WriteByte('-')
}
l := len(s)
commaIndex := 3 - ((l - startOffset) % 3)
if (commaIndex == 3) {
commaIndex = 0
}
for i := startOffset; i < l; i++ {
if (commaIndex == 3) {
buff.WriteRune(sep)
commaIndex = 0
}
commaIndex++
buff.WriteByte(s[i])
}
return buff.String()
}
英文:
Here is a function that takes an integer and grouping separator and returns a string delimited with the specified separator. I have tried to optimize for efficiency, no string concatenation or mod/division in the tight loop. From my profiling it is more than twice as fast as the humanize.Commas implementation (~680ns vs 1642ns) on my Mac. I am new to Go, would love to see faster implementations!
Usage: s := NumberToString(n int, sep rune)
Examples
Illustrates using different separator (',' vs ' '), verified with int value range.
s:= NumberToString(12345678, ',')
=> "12,345,678"
s:= NumberToString(12345678, ' ')
=> "12 345 678"
s: = NumberToString(-9223372036854775807, ',')
=> "-9,223,372,036,854,775,807"
Function Implementation
func NumberToString(n int, sep rune) string {
s := strconv.Itoa(n)
startOffset := 0
var buff bytes.Buffer
if n < 0 {
startOffset = 1
buff.WriteByte('-')
}
l := len(s)
commaIndex := 3 - ((l - startOffset) % 3)
if (commaIndex == 3) {
commaIndex = 0
}
for i := startOffset; i < l; i++ {
if (commaIndex == 3) {
buff.WriteRune(sep)
commaIndex = 0
}
commaIndex++
buff.WriteByte(s[i])
}
return buff.String()
}
答案7
得分: 9
这是一个使用正则表达式的简单函数:
import (
"regexp"
)
func formatCommas(num int) string {
str := fmt.Sprintf("%d", num)
re := regexp.MustCompile("(\\d+)(\\d{3})")
for n := ""; n != str; {
n = str
str = re.ReplaceAllString(str, "$1,$2")
}
return str
}
示例:
fmt.Println(formatCommas(1000))
fmt.Println(formatCommas(-1000000000))
输出:
1,000
-1,000,000,000
https://play.golang.org/p/vnsAV23nUXv
英文:
Here's a simple function using regex:
import (
"regexp"
)
func formatCommas(num int) string {
str := fmt.Sprintf("%d", num)
re := regexp.MustCompile("(\\d+)(\\d{3})")
for n := ""; n != str; {
n = str
str = re.ReplaceAllString(str, "$1,$2")
}
return str
}
Example:
fmt.Println(formatCommas(1000))
fmt.Println(formatCommas(-1000000000))
Output:
1,000
-1,000,000,000
答案8
得分: 8
我对之前回答中提供的解决方案的性能产生了兴趣,并编写了对它们进行基准测试的测试,其中包括两个我自己的代码片段。以下结果是在2018年的MacBook上测量的,i7 2.6GHz:
+---------------------+-------------------------------------------+--------------+
| 作者 | 描述 | 结果 |
|---------------------|-------------------------------------------|--------------|
| 我自己 | 除以1,000并附加组 | 3,472 ns/op |
| 我自己 | 插入逗号到数字组 | 2,662 ns/op |
| @icza | 逐位收集到输出数组 | 1,695 ns/op |
| @dolmen | 复制数字组到输出数组 | 1,797 ns/op |
| @Ivan Tung | 逐位写入缓冲区 | 2,753 ns/op |
| @jchavannes | 使用正则表达式插入逗号 | 63,995 ns/op |
| @Steffi Keran Rani, | 使用github.com/dustin/go-humanize | 3,525 ns/op |
| @abourget, @Dustin | | |
| @dolmen | 使用golang.org/x/text/message | 12,511 ns/op |
+---------------------+-------------------------------------------+--------------+
- 如果你想要最快的解决方案,请使用@icza的代码片段。尽管它是逐位处理而不是每三位一组处理,但它被证明是最快的。
- 如果你想要最短的合理代码片段,请查看下面的我的代码。它增加了最快解决方案的一半以上的时间,但代码长度缩短了三倍。
- 如果你想要一个一行代码的解决方案,并且不介意使用外部库,请选择github.com/dustin/go-humanize。它比最快的解决方案慢两倍以上,但该库可能会帮助你进行其他格式化。
- 如果你想要本地化输出,请选择golang.org/x/text/message。它比最快的解决方案慢七倍,但匹配消费者的语言的奢侈性是有代价的。
其他手写的解决方案也很快,选择任何一个都不会后悔,除了使用正则表达式。使用正则表达式需要最短的代码片段,但性能如此糟糕,不值得。
我对这个主题的贡献,你可以在playground上尝试运行:
func formatInt(number int) string {
output := strconv.Itoa(number)
startOffset := 3
if number < 0 {
startOffset++
}
for outputIndex := len(output); outputIndex > startOffset; {
outputIndex -= 3
output = output[:outputIndex] + "," + output[outputIndex:]
}
return output
}
英文:
I got interested in the performance of solutions offered in earlier answers and wrote tests with benchmarks for them, including two code snippets of mine. The following results were measured on MacBook 2018, i7 2.6GHz:
+---------------------+-------------------------------------------+--------------+
| Author | Description | Result |
|---------------------|-------------------------------------------|--------------|
| myself | dividing by 1,000 and appending groups | 3,472 ns/op |
| myself | inserting commas to digit groups | 2,662 ns/op |
| @icza | collecting digit by digit to output array | 1,695 ns/op |
| @dolmen | copying digit groups to output array | 1,797 ns/op |
| @Ivan Tung | writing digit by digit to buffer | 2,753 ns/op |
| @jchavannes | inserting commas using a regexp | 63,995 ns/op |
| @Steffi Keran Rani, | using github.com/dustin/go-humanize | 3,525 ns/op |
| @abourget, @Dustin | | |
| @dolmen | using golang.org/x/text/message | 12,511 ns/op |
+---------------------+-------------------------------------------+--------------+
- If you want the fastest solution, grab @icza's code snippet. Although it goes digit by digit and not by groups of three digits, it emerged as the fastest.
- If you want the shortest reasonable code snippet, look at mine below. It adds more than half of the time of the fastest solution, but the code is three times shorter.
- If you want a one-liner and do not mind using an external library, go for github.com/dustin/go-humanize. It is more than twice slower as the fastest solution, but the library might help you with other formatting.
- If you want localized output, choose golang.org/x/text/message. It is seven times slower than the fastest solution, but the luxury of matching the consumer's language does not come free.
Other hand-coded solutions are fast too and you will not regret choosing any of them, except for the usage of regexp. Using regexp needs the shortest code snippet, but the performance is so tragic, that it is not worth it.
My contribution to this topic, which you can try running in the playground:
func formatInt(number int) string {
output := strconv.Itoa(number)
startOffset := 3
if number < 0 {
startOffset++
}
for outputIndex := len(output); outputIndex > startOffset; {
outputIndex -= 3
output = output[:outputIndex] + "," + output[outputIndex:]
}
return output
}
答案9
得分: 3
这绝对不是基准测试的领导者,但如果代码清晰且性能不关键,谁在乎呢?
package main
import (
"fmt"
)
func IntComma(i int) string {
if (i < 0) {
return "-" + IntComma(-i)
}
if (i < 1000) {
return fmt.Sprintf("%d",i)
}
return IntComma(i / 1000) + "," + fmt.Sprintf("%03d",i % 1000)
}
func main() {
fmt.Println(IntComma(1234567891234567))
}
而这是用于基准测试的代码:实现与icza的非常相似
func IntCommaB(num int) string {
str := strconv.Itoa(num)
l_str := len(str)
digits := l_str
if num < 0 {
digits--
}
commas := (digits + 2) / 3 - 1
l_buf := l_str + commas
var sbuf [32]byte // 预先在堆栈上分配缓冲区,而不是使用make([]byte,n)
buf := sbuf[0:l_buf]
// 从末尾复制str
for s_i, b_i, c3 := l_str-1, l_buf-1, 0; ; {
buf[b_i] = str[s_i]
if s_i == 0 {
return string(buf)
}
s_i--
b_i--
// 每3个字符插入一个逗号
c3++
if c3 == 3 && (s_i > 0 || num>0) {
buf[b_i] = ','
b_i--
c3 = 0
}
}
}
对于输入-1234567890123456789,它比icza的快大约15%。
英文:
This is definitely not a leader of the benchmarks but who cares if code is clear and the performance is not critical?
package main
import (
"fmt"
)
func IntComma(i int) string {
if (i < 0) {
return "-" + IntComma(-i)
}
if (i < 1000) {
return fmt.Sprintf("%d",i)
}
return IntComma(i / 1000) + "," + fmt.Sprintf("%03d",i % 1000)
}
func main() {
fmt.Println(IntComma(1234567891234567))
}
And this is for the benchmarks: implementation is very similar to that of icza
func IntCommaB(num int) string {
str := strconv.Itoa(num)
l_str := len(str)
digits := l_str
if num < 0 {
digits--
}
commas := (digits + 2) / 3 - 1
l_buf := l_str + commas
var sbuf [32]byte // pre allocate buffer at stack rather than make([]byte,n)
buf := sbuf[0:l_buf]
// copy str from the end
for s_i, b_i, c3 := l_str-1, l_buf-1, 0; ; {
buf[b_i] = str[s_i]
if s_i == 0 {
return string(buf)
}
s_i--
b_i--
// insert comma every 3 chars
c3++
if c3 == 3 && (s_i > 0 || num>0) {
buf[b_i] = ','
b_i--
c3 = 0
}
}
}
With input -1234567890123456789 it is about 15% faster than icza's
答案10
得分: 2
使用https://github.com/dustin/go-humanize .. 它有很多辅助函数来处理这些事情。除了以字节为单位的MiB、MB和其他好东西。
英文:
Use https://github.com/dustin/go-humanize .. it has a bunch of helpers to deal with those things. In addition to bytes as MiB, MB, and other goodies.
答案11
得分: 0
The package humanize can do the magic! Refer the documentation of this package here. To use this package, install it first by using a tool like Git SCM. If you are using Git Bash, open the shell window and type:
go get -u github.com/dustin/go-humanize
Once this is done, you can use the following solution code (Say, main.go):
package main
import (
"fmt"
"github.com/dustin/go-humanize"
)
func main() {
fmt.Println(humanize.Commaf(float64(123456789)));
fmt.Println(humanize.Commaf(float64(-1000000000)));
fmt.Println(humanize.Commaf(float64(-100000.005)));
fmt.Println(humanize.Commaf(float64(100000.000)));
}
There are other variations to Commaf
like BigComma, Comma, BigCommaf
etc. which depends on the data type of your input.
So, on running this program using the command:
go run main.go
You will see an output such as this:
123,456,789
-1,000,000,000
-100,000.005
100,000
英文:
The package humanize can do the magic! Refer the documentation of this package here. To use this package, install it first by using a tool like Git SCM. If you are using Git Bash, open the shell window and type:
go get -u github.com/dustin/go-humanize
Once this is done, you can use the following solution code (Say, main.go):
package main
import (
"fmt"
"github.com/dustin/go-humanize"
)
func main() {
fmt.Println(humanize.Commaf(float64(123456789)));
fmt.Println(humanize.Commaf(float64(-1000000000)));
fmt.Println(humanize.Commaf(float64(-100000.005)));
fmt.Println(humanize.Commaf(float64(100000.000)));
}
There are other variations to Commaf
like BigComma, Comma, BigCommaf
etc. which depends on the data type of your input.
So, on running this program using the command:
go run main.go
You will see an output such as this:
123,456,789
-1,000,000,000
-100,000.005
100,000
答案12
得分: 0
你也可以使用这个小包:https://github.com/floscodes/golang-thousands。
只需将你的数字转换为字符串,然后像这样使用Separate
函数:
n := "3478686" // 你的数字作为字符串
thousands.Separate(n, "en") // 添加千位分隔符。第二个参数设置语言模式。
英文:
You can also use this small package: https://github.com/floscodes/golang-thousands.
Just convert your number to a string an then use the Separate
-function like this:
n:="3478686" // your number as a string
thousands.Separate(n, "en") // adds thousands separators. the second argument sets the language mode.
答案13
得分: -2
如果您不想使用库(无论出于什么原因),我写了这个代码。它似乎可以工作,并且可以使用任何指定的符号作为分隔符:
import (
"strconv"
)
func delimitNumeral(i int, delim rune) string {
src := strconv.Itoa(i)
strLen := utf8.RuneCountInString(src)
outStr := ""
digitCount := 0
for i := strLen - 1; i >= 0; i-- {
outStr = src[i:i+1] + outStr
if digitCount == 2 {
outStr = string(delim) + outStr
digitCount = 0
} else {
digitCount++
}
}
return outStr
}
**注意:**经过进一步测试,这个函数并不完美。我建议使用@IvanTung发布的解决方案,并欢迎任何可以使我的代码完美工作的修改。
英文:
If you don't want to use a library (for whatever reason), I knocked this up. It seems to work and can use any specified rune as a delimiter:
import (
"strconv"
)
func delimitNumeral(i int, delim rune) string {
src := strconv.Itoa(i)
strLen := utf8.RuneCountInString(src)
outStr := ""
digitCount := 0
for i := strLen - 1; i >= 0; i-- {
outStr = src[i:i+1] + outStr
if digitCount == 2 {
outStr = string(delim) + outStr
digitCount = 0
} else {
digitCount++
}
}
return outStr
}
Note: after further testing, this function doesn't work perfectly. I would suggest using the solution posted by @IvanTung, and welcome any edits from anyone who can get mine to work perfectly.
答案14
得分: -3
func commas(s string) string {
if len(s) <= 3 {
return s
} else {
return commas(s[0:len(s)-3]) + "," + s[len(s)-3:]
}
}
func toString(f float64) string {
parts := strings.Split(fmt.Sprintf("%.2f", f), ".")
if parts[0][0] == '-' {
return "-" + commas(parts[0][1:]) + "." + parts1
}
return commas(parts[0]) + "." + parts1
}
英文:
import ("fmt"; "strings")
func commas(s string) string {
if len(s) <= 3 {
return s
} else {
return commas(s[0:len(s)-3]) + "," + s[len(s)-3:]
}
}
func toString(f float64) string {
parts := strings.Split(fmt.Sprintf("%.2f", f), ".")
if parts[0][0] == '-' {
return "-" + commas(parts[0][1:]) + "." + parts[1]
}
return commas(parts[0]) + "." + parts[1]
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论