将浮点数格式化为n位小数,并且没有尾随的零。

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

Format a float to n decimal places and no trailing zeros

问题

我想要显示一个浮点数,整数部分全部显示,小数部分最多显示两位小数,不显示尾随的零。

// 期望的输出:
// "1.9"
// "10.9"
// "100.9"

fmt.Println("2g:")
fmt.Println(fmt.Sprintf("%.2g", 1.900))    // 输出 "1.9"
fmt.Println(fmt.Sprintf("%.2g", 10.900))   // 输出 "11"
fmt.Println(fmt.Sprintf("%.2g", 100.900))  // 输出 "1e+02"

fmt.Println("\n2f:")
fmt.Println(fmt.Sprintf("%.2f", 1.900))    // 输出 "1.90"
fmt.Println(fmt.Sprintf("%.2f", 10.900))   // 输出 "10.90"
fmt.Println(fmt.Sprintf("%.2f", 100.900))  // 输出 "100.90"

使用2g格式化存在一个问题,当整数部分增加数量级时,它开始四舍五入。而且,有时会显示带有e的数字。

使用2f格式化存在一个问题,它会显示尾随的零。我可以编写一个后处理函数来删除尾随的零,但我更愿意使用Sprintf来完成。

是否可以使用Sprintf以一种通用的方式实现这个要求?如果不行,有什么好的方法可以做到这一点?

英文:

I want to display a float with the entire integer part and up to two decimals for the fractional part, without trailing zeros.

http://play.golang.org/p/mAdQl6erWX:

// Desired output: 
// "1.9"
// "10.9"
// "100.9"

fmt.Println("2g:")
fmt.Println(fmt.Sprintf("%.2g", 1.900)) // outputs "1.9"
fmt.Println(fmt.Sprintf("%.2g", 10.900)) // outputs "11"
fmt.Println(fmt.Sprintf("%.2g", 100.900)) // outputs "1e+02"

fmt.Println("\n2f:")
fmt.Println(fmt.Sprintf("%.2f", 1.900)) // outputs "1.90"
fmt.Println(fmt.Sprintf("%.2f", 10.900)) // outputs "10.90"
fmt.Println(fmt.Sprintf("%.2f", 100.900)) // outputs "100.90"

Formatting with 2g has the problem that it starts rounding when the integer increases order of magnitudes. Also, it sometimes displays numbers with an e.

Formatting with 2f has the problem that it will display trailing zeros. I could write a post-processing function that removes trailing zeros, but I rather do this with Sprintf.

Can this be done in a generic way using Sprintf?
If not, what's a good way to do this?

答案1

得分: 81

strconv.FormatFloat(10.900, 'f', -1, 64)

这将得到 10.9

第三个参数 -1 告诉函数打印出最少的数字以准确表示浮点数。

参考链接:https://golang.org/pkg/strconv/#FormatFloat

英文:

strconv.FormatFloat(10.900, 'f', -1, 64)

This will result in 10.9.

The -1 as the third parameter tells the function to print the fewest digits necessary to accurately represent the float.

See here: https://golang.org/pkg/strconv/#FormatFloat

答案2

得分: 7

不确定Sprintf的情况,但要使其工作,可以先去掉右边的0,然后再去掉.

fmt.Println(strings.TrimRight(strings.TrimRight(fmt.Sprintf("%.2f", 100.900), "0"), ".")) // 100.9
fmt.Println(strings.TrimRight(strings.TrimRight(fmt.Sprintf("%.2f", 100.0), "0"), ".")) // 100

以上代码可以将数字格式化为保留两位小数,并去除末尾多余的0.

英文:

Not sure for Sprintf but to make it worked. Just trim right, first 0 then ..

fmt.Println(strings.TrimRight(strings.TrimRight(fmt.Sprintf("%.2f", 100.900), "0"), ".")) // 100.9
fmt.Println(strings.TrimRight(strings.TrimRight(fmt.Sprintf("%.2f", 100.0), "0"), ".")) // 100

答案3

得分: 5

我使用以下函数来实现相同的功能:

// 使用 "45" 返回 45.00,使用 "45.5" 返回 45.50
func betterFormat(num float32) string {
	s := fmt.Sprintf("%.4f", num)
	return strings.TrimRight(strings.TrimRight(s, "0"), ".")
}
英文:

I used the below func to achive the same:

//return 45.00 with "45" or 45.50 with "45.5"
func betterFormat(num float32) string {
	s := fmt.Sprintf("%.4f", num)
	return strings.TrimRight(strings.TrimRight(s, "0"), ".")
}

答案4

得分: 1

使用以下函数来格式化和控制数字的位数。

func FormatFloat(num float64, prc int) string {
    var (
        zero, dot = "0", "."

        str = fmt.Sprintf("%.+"+strconv.Itoa(prc)+"f", num)
    )
    
    return strings.TrimRight(strings.TrimRight(str, zero), dot)
}

这是一个示例:

// 将 18.24100100 转换为 18.24
fmt.Println(FormatFloat(18.24100100, 2))
英文:

Use the below function to format and control the number of digits.

func FormatFloat(num float64, prc int) string {
	var (
		zero, dot = "0", "."

		str = fmt.Sprintf("%."+strconv.Itoa(prc)+"f", num)
	)
	
	return strings.TrimRight(strings.TrimRight(str, zero), dot)
}

Here is an example:

// Converts 18.24100100 to 18.24
fmt.Println(FormatFloat(18.24100100, 2))

答案5

得分: 0

我们必须自己去除这些零。我们可以使用TrimRight(priceStr, "0."),但我写了一个更快的修剪器。

func formatPrice(price float32) string {
    // 截断小数点后的3位
    priceStr := strconv.FormatFloat(float64(price), 'f', 3, 32)
    priceStr = trimFloatTrailingZeros(priceStr)
    return priceStr
}

// trimFloatTrailingZeros 函数用于修剪 FormatFloat 添加的填充零,例如将 20.900 修剪为 20.9 或将 10.0 修剪为 10
// 注意:数字必须包含小数点,例如作为格式化的结果
func trimFloatTrailingZeros(s []byte) []byte {
    i := len(s) - 1
    for ; i >= 1; i-- {
        digit := s[i]
        if digit == '0' {
        } else {
            if digit == '.' {
                return s[:i]
            } else {
                return s[:i+1]
            }
        }
    }
    return s
}
英文:

We must trim those zeros ourselves. We can use TrimRight(priceStr, "0.") but I wrote more faster trimmer

func formatPrice(price float32) string {
	// truncate to 3 digits after point
	priceStr := strconv.FormatFloat(float64(price), 'f', 3, 32)
	priceStr = trimFloatTrailingZeros(priceStr)
	return priceStr
}

// trimFloatTrailingZeros the FormatFloat add padding zeros e.g. 20.900 to 20.9 or 10.0 to 10
// Note: the number must contain the decimal dot e.g. as result of format
func trimFloatTrailingZeros2(s []byte) []byte {
	i := len(s) - 1
	for ; i >= 1; i-- {
		digit := s[i]
		if digit == '0' {
		} else {
			if digit == '.' {
				return s[:i]
			} else {
				return s[:i+1]
			}
		}
	}
	return s
}

huangapple
  • 本文由 发表于 2015年7月8日 18:03:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/31289409.html
匿名

发表评论

匿名网友

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

确定