当开始使用浮点类型(float32& float64)时,我感到非常惊讶。 在这个例子中,我只从集合中收集了几个选项:
package main
import (
"fmt"
)
func main() {
var sum, price, count float64
sum, price, count = 1000, 166.67, 5
fmt.Printf("%v - %v * %v = %v\n", sum, price, count, sum-price*count)
price, count = 7.35, 3
fmt.Printf("%v * %v = %v\n", price, count, price*count)
var a, b, c float64
a, b = 2, 1.1
fmt.Printf("%v - %v = %v\n", a, b, a-b)
a, b, c = 0.1, 0.2, 0.3
fmt.Printf("%v + %v - %v = %v\n", a, b, c, a+b-c)
}
打印:
1000 - 166.67 * 5 = 166.6500000000001
7.35 * 3 = 22.049999999999997
2 - 1.1 = 0.8999999999999999
0.1 + 0.2 - 0.3 = 5.551115123125783e-17
2.4 / 0.1 = 23.999999999999996
执行算术运算后出现问题:+, - ,*,/
现在我绝对不确定我的算法会给我正确的结果。
我通过在每次操作后对值进行归一化来解决问题 - 舍入到比错误更低的精度:
package main
import (
"fmt"
"math"
)
func main() {
var sum, price, count float64
sum, price, count = 1000, 166.67, 5
fmt.Printf("%v - %v * %v = %v\n", sum, price, count, Normalize(sum-price*count))
price, count = 7.35, 3
fmt.Printf("%v * %v = %v\n", price, count, Normalize(price*count))
var a, b, c float64
a, b = 2, 1.1
fmt.Printf("%v - %v = %v\n", a, b, Normalize(a-b))
a, b, c = 0.1, 0.2, 0.3
fmt.Printf("%v + %v - %v = %v\n", a, b, c, Normalize(a+b-c))
a, b = 2.4, 0.1
fmt.Printf("%v / %v = %v\n", a, b, Normalize(a/b))
}
func Normalize(value float64) float64 {
return RoundViaFloat(value, 4)
}
func RoundViaFloat(x float64, prec int) float64 {
var rounder float64
pow := math.Pow(10, float64(prec))
intermed := x * pow
_, frac := math.Modf(intermed)
x = .5
if frac < 0.0 {
x = -.5
}
if frac >= x {
rounder = math.Ceil(intermed)
} else {
rounder = math.Floor(intermed)
}
return rounder / pow
}
打印:
1000 - 166.67 * 5 = 166.65
7.35 * 3 = 22.05
2 - 1.1 = 0.9
0.1 + 0.2 - 0.3 = 0
2.4 / 0.1 = 24
但在我看来,这是不正常的: - (
任何人都可以帮我解决这个问题吗?
感谢名单