20

使用 Go 我试图找到将浮点数格式化为字符串的“最佳”方法。我一直在寻找示例,但是我找不到任何可以专门回答我的问题的东西。我要做的就是使用“最佳”方法将浮点数格式化为字符串。小数位数可能会有所不同,但将是已知的(例如 2 或 4 或零)。下面是我想要实现的一个示例。

根据下面的示例,我应该使用fmt.Sprintf()还是strconv.FormatFloat()其他?

而且,每个的正常用法和每个之间的区别是什么?

我也不明白在以下当前有 32 的情况下使用 32 或 64 的重要性:

strconv.FormatFloat(float64(fResult), 'f', 2, 32)

例子:

package main

import (
    "fmt"
    "strconv"
)

func main() {

    var (
        fAmt1 float32 = 999.99
        fAmt2 float32 = 222.22
    )

    var fResult float32 = float32(int32(fAmt1*100) + int32(fAmt2*100)) / 100

    var sResult1 string = fmt.Sprintf("%.2f", fResult)

    println("Sprintf value = " + sResult1)

    var sResult2 string = strconv.FormatFloat(float64(fResult), 'f', 2, 32)

    println("FormatFloat value = " + sResult2)

}
4

2 回答 2

21

两者都fmt.Sprintfstrconv.FormatFloat幕后使用相同的字符串格式化例程,因此应该给出相同的结果。

如果数字应该被格式化的精度是可变的,那么它可能更容易使用FormatFloat,因为它避免了像使用Sprintf. 如果它永远不会改变,那么你可以使用任何一个。

最后一个参数FormatFloat控制值如何四舍五入。从文档中:

假设原始值是从 bitSize 位的浮点值(32 为 float32,64 为 float64)获得的,它对结果进行四舍五入

因此,如果您使用float32示例代码中的值,那么传递32是正确的。

于 2013-09-23T03:49:27.877 回答
3

您将使用 Go 1.12(2019 年 2 月)和项目cespare/ryu获得 strconv 的更快替代方案:

Ryu是 Ryu 的 Go 实现,Ryu 是一种将浮点数转换为字符串的快速算法。
它是Ulf Adams 的 C 库的相当直接的 Go 翻译。

strconv.FormatFloat延迟是双峰的,因为不经常采用的慢速路径要贵几个数量级(问题 15672)。

Ryu 算法需要几个查找表。
Ulf Adams 的 C 库实现了大小优化 ( RYU_OPTIMIZE_SIZE),它大大减少了float64表的大小,以换取更多的 CPU 成本。

对于一小部分输入,Ryu 给出的值strconv与最后一位不同。
这是由于问题 29491strconv中的一个错误造成的。

Go 1.12 可能会或可能不会直接在 strconv 中包含该新实现,但如果没有,您可以使用此项目进行更快的转换。

于 2019-01-14T17:14:49.720 回答