golang float64变量加减运算后小数会突然变多,怎么解决?

kiyoma
  • 39
package float_calc

import "fmt"

func Main() {
    var floatNumbers = []float64{1, 1, 1, 1, 1, 1, 1}

    var sum float64
    sum = 0

    for _, floatNumber := range floatNumbers {
        sum += floatNumber - 0.01
        fmt.Println(sum)
    }
}

结果如下:

0.99
1.98
2.9699999999999998
3.96
4.95
5.94
6.930000000000001

求解决方案

回复
阅读 3.6k
4 个回答

四舍五入保留有效位数吧,这和语言没有关系,而是浮点数表示通用的问题,去了解下浮点数在计算机中的表示规则吧。

浮点数不能用数值精确赋值,如果你想要每次输出都保留一样的小数点后x位,可以用printf。
但我这边实测输出来的没你这个这么长

fmt.Printf("%.2f\n", n);
LetsGo
  • 2
新手上路,请多包涵

自己用字符串为依托解析为整数然后计算

浮点数的精度问题不仅在 Golang 语言中存在,在其他语言中也存在。

比如 JavaScript :
image.png

Go 语言支持两种浮点数据类型,float32 和 float64 。均遵循算术规范 IEEE-754 国际标准,同时现代 CPU 都实现了该规范。

楼主的问题产生在中间过程不一致导致的不一样的结果,我们可以统一一起进行计算不进行中间落地存储。上面代码可调整为:

package main

import "fmt"

func main() {
    var floatNumbers = []float64{1, 2, 3, 4, 5, 6, 7}
    //var sum float64
    //sum = 0
    for _, floatNumber := range floatNumbers {
        //sum += floatNumber - 0.01
        //fmt.Println(sum)
        fmt.Println(floatNumber - 0.01)
    }
}

Run

// OutPut
0.99
1.99
2.99
3.99
4.99
5.99
6.99

楼上提到的通过 fmt.Printf() 或 四舍五入(记得尾差处理)也是不错的方案;写代码除了搞清楚原理外,我们还需要清楚运用的场景,具体问题在具体分析。

你知道吗?

宣传栏