dop83362 2016-04-09 10:54
浏览 41
已采纳

是否有任何标准库可以将float64转换为具有最大有效位数的固定宽度的字符串?

Imagine for printing in a 12 fixed width table we need printing float64 numbers:

fmt.Printf("%12.6g
", 9.405090880450127e+119) //"9.40509e+119"
fmt.Printf("%12.6g
", 0.1234567890123)        //"    0.123457"
fmt.Printf("%12.6g
", 123456789012.0)         //" 1.23457e+11"

We prefer 0.1234567890 to " 0.123457" we lose 6 significant digits.
We prefer 123456789012 to " 1.23457e+11" we lose 6 significant digits.

Is there any standard library to convert float64 to string with fix width with maximum number of significant digits? Thanks in Advance.

  • 写回答

1条回答 默认 最新

  • dongxiaoke2018 2016-04-09 14:33
    关注

    Basically you have 2 output formats: either a scientific notation or a regular form. The turning point between those 2 formats is 1e12.

    So you can branch if x >= 1e12. In both branches you may do a formatting with 0 fraction digits to see how long the number will be, so you can calculate how many fraction digits will fit in for 12 width, and so you can construct the final format string, using the calculated precision.

    The pre-check is required in the scientific notation too (%g), because the width of exponent may vary (e.g. e+1, e+10, e+100).

    Here is an example implementation. This is to get you started, but it does not mean to handle all cases, and it is not the most efficient solution (but relatively simple and does the job):

    // format12 formats x to be 12 chars long.
    func format12(x float64) string {
        if x >= 1e12 {
            // Check to see how many fraction digits fit in:
            s := fmt.Sprintf("%.g", x)
            format := fmt.Sprintf("%%12.%dg", 12-len(s))
            return fmt.Sprintf(format, x)
        }
    
        // Check to see how many fraction digits fit in:
        s := fmt.Sprintf("%.0f", x)
        if len(s) == 12 {
            return s
        }
        format := fmt.Sprintf("%%%d.%df", len(s), 12-len(s)-1)
        return fmt.Sprintf(format, x)
    }
    

    Testing it:

    fs := []float64{0, 1234.567890123, 0.1234567890123, 123456789012.0, 1234567890123.0,
        9.405090880450127e+9, 9.405090880450127e+19, 9.405090880450127e+119}
    
    for _, f := range fs {
        fmt.Println(format12(f))
    }
    

    Output (try it on the Go Playground):

    0.0000000000
    0.1234567890
    1234.5678901
    123456789012
    1.234568e+12
    9405090880.5
    9.405091e+19
    9.40509e+119
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 用雷电模拟器安装百达屋apk一直闪退
  • ¥15 算能科技20240506咨询(拒绝大模型回答)
  • ¥15 自适应 AR 模型 参数估计Matlab程序
  • ¥100 角动量包络面如何用MATLAB绘制
  • ¥15 merge函数占用内存过大
  • ¥15 Revit2020下载问题
  • ¥15 使用EMD去噪处理RML2016数据集时候的原理
  • ¥15 神经网络预测均方误差很小 但是图像上看着差别太大
  • ¥15 单片机无法进入HAL_TIM_PWM_PulseFinishedCallback回调函数
  • ¥15 Oracle中如何从clob类型截取特定字符串后面的字符