parsing - Golang ParseFloat 在示例中不准确

标签 parsing go

我一直在做一个项目,我必须将字符串转换为 uint,以确保一些货币值匹配:

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")
}

但是当我尝试对几个数字执行 strconv.ParseFloat(),然后尝试将它们乘以 100(以获得美分值)时,我似乎发现了一个问题。

我在这里创建了一个示例: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

在这种情况下我应该使用 ParseFloat() 吗?如果没有,我很想听听对此的简要解释,因为我仍然是一名正在学习的程序员。

最佳答案

Go 使用 IEEE-754二进制 float 。 float 是不精确的。不要将它们用于金融交易。使用整数。

例如,

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

输出:

7935 <nil>
14920 <nil>
-14920 <nil>
0 format error: 149.2

关于parsing - Golang ParseFloat 在示例中不准确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51757136/

相关文章:

html - 在 HTML 中访问 <li> 元素

json - 接口(interface)转换: interface is map[string]interface {} not

templates - FuncMap 的多个模板

json - 将选项对象解析为选项列表

python - 电子邮件作为 email.Message Python 中的类对象

parsing - 将多行合并为一个(.cap 文件)CentOS

javascript - 如何在 node.js 中实现 readUInt16BE 函数

java - 如何解析txt文件中的2列int

go - Go 方法中的默认值

go - 我应该什么时候关闭这个简单的网络应用程序中的数据库连接?