我试图将一个数字四舍五入到最接近的千,但当我使用数学时,通常会得到不同的结果。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