【问题标题】:Variable floating-point precision format string可变浮点精度格式字符串
【发布时间】:2016-01-16 16:59:26
【问题描述】:

我正在尝试将浮点数打印为百分比,并且我希望小数点后的位数根据需要而变化。目前我有:

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

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

50.00%

而我想要得到的是:

50%

格式字符串有什么方法可以指示应该使用最大 2 位精度,但仅在需要时使用?

【问题讨论】:

  • 50% 是 50% +- 0.5%; 50.00% 是 50.00% +- 0.005%。它们不一样。
  • 没错,但对于我正在做的事情,这并不重要。

标签: go format format-string


【解决方案1】:

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

但是您可以使用正则表达式删除末尾的点和零:

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

奖励:相同的正则表达式适用于任意数量的尾随零。

附注:50.0041 的显示方式与 50 的显示方式相同,这可能有点误导。

【讨论】:

    【解决方案2】:

    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)
    // 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】:

      一种方法是使用 if 语句控制打印输出,即,如果结果完全可被 1 整除(result%1 == 0),则将结果打印到小数位。否则像上面那样打印到 .2f 。不确定是否有更短的方法可以做到这一点,但我认为这应该可行。

      【讨论】:

      • 是的,这就是我想要避免的,但它可能会发生这种情况。
      • 你不能在float64上使用模数
      • 啊好吧我不知道这个。写一些基本等价的东西并不难,所以 if else 逻辑可以工作。
      猜你喜欢
      • 1970-01-01
      • 2023-03-10
      • 2021-08-02
      • 2017-05-20
      • 2013-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多