big.float setprec怪异行为

  • 本文关键字:float setprec big go
  • 更新时间 :
  • 英文 :


使用Golang的Big.Float进行一些计算后,我将精度设置为2。

,即使您的数字只是一个简单的10,在设置精度为8的精度后。

package main
import (
    "fmt"
    "math/big"
)
func main() {
    cost := big.NewFloat(10)
    fmt.Println("COST NOW", cost)
    perKWh := big.NewFloat(0)
    cost.Add(cost, perKWh)
    fmt.Println("COST ", cost.String())
    perMinute := big.NewFloat(0)
    cost.Add(cost, perMinute)
    fmt.Println("COST ", cost.String())
    discountAmount := big.NewFloat(0)
    cost.Sub(cost, discountAmount)
    floatCos, _ := cost.Float64()
    fmt.Println(fmt.Sprintf("COST FLOAT %v", floatCos))
    cost.SetPrec(2)
    fmt.Println("COST ", cost.String())
}

在这里检查游乐场示例:https://play.golang.org/p/jmcrxkd5u49

想了解为什么

来自细手册:

键入float
[...]
每个浮点值还具有精度,圆形模式和准确性。精度是可用的最大数量来表示该值。圆形模式指定了应如何将结果舍入以适合Mantissa位,并且准确性描述了相对于确切结果的舍入误差。

big.Float在内部表示为:

sign × mantissa × 2**exponent

调用SetPrec时,您将设置可用于Mantissa的 bits 的数量,而不是该号码的小数表示中的精度数字。

您不能在两个薄饼中代表十进制10(1010二进制(,因此它可以圆形到十进制8(1000个二进制(,可以适合2位。您至少需要三个位来存储十进制的101部分10。8可以适合一位Mantissa,因此如果您说cost.SetPrec(1),您会看到相同的8。

使用大包装时,您需要在二进制方面思考。

首先,丢弃所有无关的代码。接下来,打印有用的诊断信息。

package main
import (
    "fmt"
    "math/big"
)
func main() {
    cost := big.NewFloat(10)
    fmt.Println("Cost ", cost.String())
    fmt.Println("Prec", cost.Prec())
    fmt.Println("MinPrec", cost.MinPrec())
    fmt.Println("Mode", cost.Mode())
    cost.SetPrec(2)
    fmt.Println("Prec", cost.Prec())
    fmt.Println("Accuracy", cost.Acc())
    fmt.Println("Cost ", cost.String())
}

输出:

Cost  10
Prec 53
MinPrec 3
Mode ToNearestEven
Prec 2
Accuracy Below
Cost  8

第10回合至最接近的偶数数字,可以在标志,指数和2位曼陀萨中表示,您将获得8。

四舍五入tonearesteven是IEE754圆形。圆形到最近,与均匀的联系 - 圆形到最近的值;如果数字中途下降,则将其四舍五入到最近的值,均匀(零(最小的位。

最新更新