Golang浮点数相加出现意外结果怎么办

Golang浮点数相加出现意外结果怎么办 以下代码片段

import "fmt"

func main() {
	a := 8.9
	b := 2.2
	c := a + b
	fmt.Printf("%g\n", c)
}

返回 11.100000000000001,但我期望的是 11.1

我哪里做错了?

谢谢

4 回复

感谢两位,我本该知道的

更多关于Golang浮点数相加出现意外结果怎么办的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这只是浮点数的问题……

如果你需要精确的结果,就不要使用浮点数。

一些背景信息:

https://0.30000000000000004.com/

你好!在 Go 中,如果你想正确格式化一个带有特定小数位数的 float 数字,你需要使用 %.Nf,其中 N 是你想要的位数。

在你的情况下,将:

fmt.Printf("%g\n", c)

改为 fmt.Printf("%.1f\n", c)。格式化符号 %g 使用最大有效位数来表示浮点数,而在你的例子中,你使用了两个 float64,所以 Go 会自动填充右侧的所有 14 位数字。

这是因为浮点数在计算机中是以二进制近似表示的,存在精度限制。Go语言中的float64类型遵循IEEE 754标准,某些十进制小数无法精确表示为二进制浮点数,导致舍入误差。

示例代码:

package main

import (
    "fmt"
)

func main() {
    a := 8.9
    b := 2.2
    c := a + b
    
    // 直接打印会显示精度误差
    fmt.Printf("直接相加: %g\n", c) // 输出: 11.100000000000001
    
    // 方法1: 使用格式化输出控制精度
    fmt.Printf("格式化输出: %.1f\n", c) // 输出: 11.1
    
    // 方法2: 使用decimal类型进行精确计算
    // 需要导入第三方库,例如: "github.com/shopspring/decimal"
}

对于需要精确计算的场景(如金融计算),建议使用decimal类型。安装第三方库:

go get github.com/shopspring/decimal

使用示例:

package main

import (
    "fmt"
    "github.com/shopspring/decimal"
)

func main() {
    a := decimal.NewFromFloat(8.9)
    b := decimal.NewFromFloat(2.2)
    c := a.Add(b)
    
    fmt.Println("精确计算:", c) // 输出: 11.1
}

对于一般场景,可以通过格式化输出来控制显示精度,但需要注意这不会改变实际存储的浮点数值。

回到顶部