duanaidang6197 2018-08-08 23:55
浏览 363
已采纳

Golang ParseFloat在示例中不准确

I've been working on a project where I have to convert a string to a uint, to make sure some money values are matching:

total, err := strconv.ParseFloat(paymentResp.Transactions[0].Amount.Total, 64)
if err != nil {
    return ctx.JSON(http.StatusBadRequest, err.Error())
}

if o.TotalPrice != uint(total*100) {
    return ctx.JSON(http.StatusBadRequest, "Unable to verify amount paid")
}

But I've seemingly found a problem when trying to do the strconv.ParseFloat() on a couple of numbers, then attempting to multiply them by 100 (to get the cents value).

I've created an example here: Go Playground

f, _ := strconv.ParseFloat("79.35", 64)
fmt.Println(uint(f*100))  //7934

f2, _ := strconv.ParseFloat("149.20", 64)
fmt.Println(uint(f2*100)) //14919

Is ParseFloat() what I should be using in this scenario? If not, I'd love to hear a brief explanation on this, as I'm still a programmer in learning.

  • 写回答

3条回答 默认 最新

  • douque2016 2018-08-09 12:10
    关注

    Go uses IEEE-754 binary floating-point numbers. Floating-point numbers are imprecise. Don't use them for financial transactions. Use integers.

    For example,

    package main
    
    import (
        "fmt"
        "strconv"
        "strings"
    )
    
    func parseCents(s string) (int64, error) {
        n := strings.SplitN(s, ".", 3)
        if len(n) != 2 || len(n[1]) != 2 {
            err := fmt.Errorf("format error: %s", s)
            return 0, err
        }
        d, err := strconv.ParseInt(n[0], 10, 56)
        if err != nil {
            return 0, err
        }
        c, err := strconv.ParseUint(n[1], 10, 8)
        if err != nil {
            return 0, err
        }
        if d < 0 {
            c = -c
        }
        return d*100 + int64(c), nil
    }
    
    func main() {
        s := "79.35"
        fmt.Println(parseCents(s))
        s = "149.20"
        fmt.Println(parseCents(s))
        s = "-149.20"
        fmt.Println(parseCents(s))
        s = "149.2"
        fmt.Println(parseCents(s))
    }
    

    Playground: https://play.golang.org/p/mGuO51QWyIv

    Output:

    7935 <nil>
    14920 <nil>
    -14920 <nil>
    0 format error: 149.2
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog
  • ¥15 Excel发现不可读取的内容
  • ¥15 关于#stm32#的问题:CANOpen的PDO同步传输问题