浮点数变量的精度格式字符串

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

Variable floating-point precision format string

问题

我正在尝试将浮点数以百分比形式打印出来,并且希望小数点后的位数根据需要进行变化。目前我有以下代码:

fmt.Printf("%.2f%%\n", 100*(value/total))

问题是,如果我的百分比恰好是50,我将得到以下输出:

50.00%

而我想要的是:

50%

有没有办法让格式字符串指示只在需要时使用最多2位小数精度?

英文:

I'm trying to print floating point numbers as percentages, and I'd like for the number of digits after the decimal place to vary as needed. Currently I have:

fmt.Printf("%.2f%%\n", 100*(value/total))

The problem is that if my percentage is, say, exactly 50, I will get the following output:

50.00%

While what I want is to get:

50%

Is there any way for the format string to indicate that a maximum of 2 digits of precision should be used, but only if needed?

答案1

得分: 2

fmt包中没有直接的解决方案。

但是你可以使用正则表达式来去除末尾的小数点和零:

r, _ := regexp.Compile(`\.?0*$`)
fmt.Printf("%s%%\n", r.ReplaceAllString(fmt.Sprintf("%.2f", 100*(value/total)),""))

额外提示:相同的正则表达式也适用于任意数量的尾随零。

顺便提一下:你将以相同的方式显示50.004150,这可能会有点误导。

英文:

There's no direct solution with the fmt package.

But you can remove the dot and zeros at end with a regular expression:

r, _ := regexp.Compile(`\.?0*$`)
fmt.Printf("%s%%\n", r.ReplaceAllString(fmt.Sprintf("%.2f", 100*(value/total)),""))

Bonus: the same regex works for any number of trailing zeros.

Side note: You'll display 50.0041 the same way than 50, which might be a little misleading.

答案2

得分: 1

fmt中没有办法通过其他标志或方法来实现这一点。你需要自己编写逻辑。你可以这样做:

var final string
doubledecimal := fmt.Sprintf("%.2f", 100*value/total)
if doubledecimal[len(doubledecimal)-2:] == "00" {
    final = doubledecimal[:len(doubledecimal)-3]
} else {
    final = doubledecimal
}
fmt.Printf("%s%%\n", final)

你也可以使用strings.Split来分割小数点并进行处理。

你甚至可以将50.10%转换为50.1%

doubledecimal := fmt.Sprintf("%.2f", 100*value/total)
// 去除尾部的零
for doubledecimal[len(doubledecimal)-1] == '0' {
    doubledecimal = doubledecimal[:len(doubledecimal)-1]
}
// 如果小数点在尾部,则去除小数点
if doubledecimal[len(doubledecimal)-1] == '.' {
    doubledecimal = doubledecimal[:len(doubledecimal)-1]
}
fmt.Printf("%s%%\n", doubledecimal)
英文:

There's no way to do that inside fmt with e.g. another flag or what have you. You'll have to write out the logic yourself. You could do something like:

var final string
doubledecimal := fmt.Sprintf("%.2f", 100*value/total)
if doubledecimal[len(doubledecimal)-2:] == "00" {
	final = doubledecimal[:len(doubledecimal)-3]
} else {
	final = doubledecimal
}
fmt.Printf("%s%%\n, final)

You could similarly use strings.Split to split on the decimal point and work from there.

You could even adjust this to turn 50.10% into 50.1%.

doubledecimal := fmt.Sprintf("%.2f", 100*value/total)
// Strip trailing zeroes
for doubledecimal[len(doubledecimal)-1] == 0 {
    doubledecimal = doubledecimal[:len(doubledecimal)-1]
}
// Strip the decimal point if it's trailing.
if doubledecimal[len(doubledecimal)-1] == "." {
    doubledecimal = doubledecimal[:len(doubledecimal)-1]
}
fmt.Printf("%s%%\n", doubledecimal)

答案3

得分: 0

一种方法是使用if语句来控制打印输出,即如果结果可以整除1(result%1 == 0),则打印结果时不显示小数位。否则,按照你上面所做的方式打印到小数点后两位。不确定是否有更简洁的方法,但我认为这应该可以工作。

英文:

One way could be to have an if statement controlling the print output, i.e. if the result is cleanly divisible by 1 (result%1 == 0) then print the result to no decimal places. Otherwise print to .2f as you've done above. Not sure if there is a shorter way of doing this, but I think this should work.

huangapple
  • 本文由 发表于 2016年1月17日 00:59:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/34829606.html
匿名

发表评论

匿名网友

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

确定