gpt4 book ai didi

go - Go中四舍五入到小数点后2位

转载 作者:IT王子 更新时间:2023-10-29 01:44:03 24 4
gpt4 key购买 nike

在 Go 中使用 math.Round() 将正值(这里的示例:1.015)四舍五入到小数点后 2 位:

fmt.Println(math.Round(1.015*100) / 100)

Go Playground

我得到:1.02。没错。

但是当我使用一个函数来完成同样的工作时:

func RoundHalfUp(x float64) float64 {
return math.Round(x*100) / 100
}

Go Playground

我得到了 1.01

RoundHalfUp 函数有什么问题?

最佳答案

The Go Programming Language Specification

Constants

Numeric constants represent exact values of arbitrary precision and do not overflow.

Implementation restriction: Although numeric constants have arbitrary precision in the language, a compiler may implement them using an internal representation with limited precision. That said, every implementation must:

  • Represent floating-point constants, including the parts of a complex constant, with a mantissa of at least 256 bits and a signed
    binary exponent of at least 16 bits.
  • Round to the nearest representable constant if unable to represent a floating-point or complex constant due to limits on precision.

These requirements apply both to literal constants and to the result of evaluating constant expressions.

Constant expressions

Constant expressions may contain only constant operands and are evaluated at compile time.

Constant expressions are always evaluated exactly; intermediate values and the constants themselves may require precision significantly larger than supported by any predeclared type in the language.

Implementation restriction: A compiler may use rounding while computing untyped floating-point or complex constant expressions; see the implementation restriction in the section on constants. This rounding may cause a floating-point constant expression to be invalid in an integer context, even if it would be integral when calculated using infinite precision, and vice versa.


像 Go 编译器对 math.Round(1.015*100)/100 那样实现 RoundHalfUp 函数。 1.015*100 是一个无类型的浮点常量表达式。使用精度至少为 256 位的 math/big 包。 Go float64(IEEE-754 64 位 float )具有 53 位精度。

例如,256位精度(常量表达式),

package main

import (
"fmt"
"math"
"math/big"
)

func RoundHalfUp(x string) float64 {
// math.Round(x*100) / 100
xf, _, err := big.ParseFloat(x, 10, 256, big.ToNearestEven)
if err != nil {
panic(err)
}
xf100, _ := new(big.Float).Mul(xf, big.NewFloat(100)).Float64()
return math.Round(xf100) / float64(100)
}

func main() {
fmt.Println(RoundHalfUp("1.015"))
}

Playground :https://play.golang.org/p/uqtYwP4o22B

输出:

1.02

如果我们只使用 53 位精度(float64):

xf, _, err := big.ParseFloat(x, 10, 53, big.ToNearestEven)

Playground :https://play.golang.org/p/ejz-wkuycaU

输出:

1.01

关于go - Go中四舍五入到小数点后2位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52712958/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com