使用 math.Pow 四舍五入到最接近的千位时的不同结果
Different results while rounding to nearest thousand using math.Pow
我试图将数字四舍五入到最接近的千位,但当我使用 math.Pow 时通常会得到不同的结果。示例:
fmt.Println(math.Pow(10., 3.))
x := math.Pow(10, 3)
y := (((3251 - 1000) / x) * x)
fmt.Println(y)
Output: 1000
Output: 2251
当我改用 1000 时 math.Pow(10., 3.) 我得到了我想要的:
y := (((3251 - 1000) / 1000) * 1000)
fmt.Println(y)
Output: 2000
我做错了什么?我将不胜感激。
表达式 y := ((3251 - 1000) / 1000) * 1000
是一个 constant expression,即只有常量无类型文字操作数,它在编译时求值。特别是:
If the untyped operands of a binary operation (other than a shift) are of different kinds, the result is of the operand's kind that appears later in this list
(除法和乘法的)最后一个操作数 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
而不是表达式不再是常数(它是函数调用的结果),现在你有一个 typed float64
变量由 Pow
的 return 类型产生:
// (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 in :
建议的技巧
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
我试图将数字四舍五入到最接近的千位,但当我使用 math.Pow 时通常会得到不同的结果。示例:
fmt.Println(math.Pow(10., 3.))
x := math.Pow(10, 3)
y := (((3251 - 1000) / x) * x)
fmt.Println(y)
Output: 1000
Output: 2251
当我改用 1000 时 math.Pow(10., 3.) 我得到了我想要的:
y := (((3251 - 1000) / 1000) * 1000)
fmt.Println(y)
Output: 2000
我做错了什么?我将不胜感激。
表达式 y := ((3251 - 1000) / 1000) * 1000
是一个 constant expression,即只有常量无类型文字操作数,它在编译时求值。特别是:
If the untyped operands of a binary operation (other than a shift) are of different kinds, the result is of the operand's kind that appears later in this list
(除法和乘法的)最后一个操作数 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
而不是表达式不再是常数(它是函数调用的结果),现在你有一个 typed float64
变量由 Pow
的 return 类型产生:
// (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 in
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