Golang中浮点数算术平均值的计算方法
Golang中浮点数算术平均值的计算方法 一个愚蠢的问题,但下面的代码片段有一个我找不到的错误
var (
an float64
n, avg = 0, 0.
)
for ; ; n++ {
fmt.Print("number? ")
fmt.Scan(&an)
if an == 0. {
break
}
avg += an
}
if n != 0 {
fmt.Println(avg / float64(n))
}
程序输出是
number? 5.1
number? 2.1
number? 0
3.5999999999999996
而不是3.6,为什么?
更多关于Golang中浮点数算术平均值的计算方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于Golang中浮点数算术平均值的计算方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
这只会导致更多问题。如果你需要精度,那么请使用具有精度的类型。
如果只是用于显示目的,那么在调用 fmt.Printf 时使用适当的注解。
fmt.Printf
好的,我通过谷歌找到了以下代码片段 https://play.golang.org/p/KNhgeuU5sT 它解决了这个问题 谢谢。
好的,你有什么建议可以让我对结果进行四舍五入吗?也许可以使用系统误差常数 .0000000000000005?
好的,在这种情况下,我可以使用 fmt.Printf 来对结果进行四舍五入,或者使用 math.big 来处理精度为 3.5999999999999996 的输入数据,对吗?
由于浮点数存在已知的不精确性问题。
如果需要精确值,就需要使用精确的类型。
关于这个话题有很多博客文章,我选取了谷歌搜索"浮点数货币"的前三个结果(因为货币是最常用的"精确值"示例):
- https://spin.atomicobject.com/2014/08/14/currency-rounding-errors/
- https://husobee.github.io/money/float/2016/09/23/never-use-floats-for-currency.html
- https://stackoverflow.com/questions/3730019/why-not-use-double-or-float-to-represent-currency
(* 我最近没有读过这些文章,它们只是谷歌搜索的前几个结果)
这是一个典型的浮点数精度问题,不是代码逻辑错误。在Go语言中,浮点数使用IEEE 754标准表示,某些十进制小数无法精确表示为二进制浮点数,导致精度损失。
你的代码计算 (5.1 + 2.1) / 2 时,5.1和2.1在二进制表示中都是近似值,累加和除法后产生了微小的误差。
以下是验证和解决方案:
package main
import (
"fmt"
"math"
)
func main() {
// 验证浮点数精度问题
fmt.Printf("5.1 的精确值: %.20f\n", 5.1)
fmt.Printf("2.1 的精确值: %.20f\n", 2.1)
fmt.Printf("和的值: %.20f\n", 5.1+2.1)
fmt.Printf("平均值: %.20f\n", (5.1+2.1)/2)
// 解决方案1:格式化输出
var (
an float64
n, avg = 0, 0.
)
for ; ; n++ {
fmt.Print("number? ")
fmt.Scan(&an)
if an == 0. {
break
}
avg += an
}
if n != 0 {
// 使用格式化输出控制精度
fmt.Printf("平均值: %.2f\n", avg/float64(n))
}
// 解决方案2:使用math.Round进行四舍五入
if n != 0 {
result := avg / float64(n)
rounded := math.Round(result*100) / 100 // 保留两位小数
fmt.Printf("四舍五入后的平均值: %.2f\n", rounded)
}
}
输出示例:
number? 5.1
number? 2.1
number? 0
平均值: 3.60
四舍五入后的平均值: 3.60
关键点:
- 浮点数运算存在固有的精度限制
- 使用
fmt.Printf格式化输出控制显示精度 - 需要精确计算时使用
math.Round等函数进行舍入处理 - 对于金融等需要精确计算的场景,建议使用
math/big包


