不同的结果,同时使用数学四舍五入到最接近的千.Pow



我试图将一个数字四舍五入到最接近的千,但当我使用数学时,通常会得到不同的结果。Pow。示例:

fmt.Println(math.Pow(10., 3.))
x := math.Pow(10, 3)
y := (((3251 - 1000) / x) * x)
fmt.Println(y)
Output: 1000
Output: 2251

GoPlayGround

当我用1000代替数学时。Pow(10.,3.(我得到了我想要的:

y := (((3251 - 1000) / 1000) * 1000)
fmt.Println(y)
Output: 2000

去游乐场

我做错了什么?我很感激你的帮助。

表达式y := ((3251 - 1000) / 1000) * 1000是一个常量表达式,即只有常量的非类型文字操作数,并且在编译时对其求值。特别是:

如果二进制运算(移位除外(的非类型化操作数属于不同类型,则结果属于此列表中稍后出现的操作数类型

最后一个操作数1000(除法和乘法(是非类型化的int,因此除法的结果也是int,并按预期截断为整数精度:

// (3251 - 1000) -> int 2251
// (3251 - 1000) / 1000 -> int 2
// ((3251 - 1000) / 1000) * 1000 -> int 2000
y := ((3251 - 1000) / 1000) * 1000
fmt.Println(reflect.TypeOf(y)) // int

使用math.Pow,表达式不再是常量(它是函数调用的结果(,现在您有了一个类型float64变量,该变量由Pow:的返回类型产生

// (3251 - 1000) -> 2251 int
// (3251 - 1000) / x -> 2.251 float64
// ((3251 - 1000) / x) * x -> 2251 float64
y := (((3251 - 1000) / x) * x)
fmt.Println(reflect.TypeOf(y)) // float64

所以在后一种情况下,除法得到的小数会被保留下来,你再乘以它就可以得到它。

游乐场:https://play.golang.org/p/v_mX3mnM6tT


要四舍五入到最接近的千,你可以使用@icza在这个答案中建议的技巧:

func Round(x, unit float64) float64 {
return math.Round(x/unit) * unit
}
func main() {
x := Round(3251-1000, 1000.)
fmt.Println(x) // 2000
}

基于建议:

package main
import (
"fmt"
"math"
)
func main() {
fmt.Println(math.Pow(10, 3))
x := math.Pow(10, 3)
y := (((3251 - 1000) / x) * x)
fmt.Println(y)
fmt.Println(Round(y, 1000))
}
func Round(x, unit float64) float64 {
return math.Round(x/unit) * unit
}

输出:

1000
2251
2000

最新更新