为了账号安全,请及时绑定邮箱和手机立即绑定

go中的浮点运算

go中的浮点运算

Go
蝴蝶刀刀 2021-06-15 17:01:38
这是 go 中的示例代码:package mainimport "fmt"func mult32(a, b float32) float32 { return a*b }func mult64(a, b float64) float64 { return a*b }func main() {    fmt.Println(3*4.3)                  // A1, 12.9    fmt.Println(mult32(3, 4.3))         // B1, 12.900001    fmt.Println(mult64(3, 4.3))         // C1, 12.899999999999999    fmt.Println(12.9 - 3*4.3)           // A2, 1.8033161362862765e-130    fmt.Println(12.9 - mult32(3, 4.3))  // B2, -9.536743e-07    fmt.Println(12.9 - mult64(3, 4.3))  // C2, 1.7763568394002505e-15    fmt.Println(12.9 - 3*4.3)                               // A4, 1.8033161362862765e-130    fmt.Println(float32(12.9) - float32(3)*float32(4.3))    // B4, -9.536743e-07    fmt.Println(float64(12.9) - float64(3)*float64(4.3))    // C4, 1.7763568394002505e-15}A1、B1 和 C1 行之间的结果差异是可以理解的。然而,从A2开始到C2的魔力来了。B2 和 C2 的结果都与 A2 行的结果不匹配。行 x2(x = A、B 或 C)也是如此——但 x2 和 x4 的输出是相同的。为了确保让我们以二进制形式打印结果。    fmt.Printf("%b\n", 3*4.3)                   // A11, 7262054399134925p-49    fmt.Printf("%b\n", mult32(3, 4.3))          // B11, 13526631p-20    fmt.Printf("%b\n", mult64(3, 4.3))          // C11, 7262054399134924p-49    fmt.Printf("%b\n", 12.9 - 3*4.3)            // A12, 4503599627370496p-483    fmt.Printf("%b\n", 12.9 - mult32(3, 4.3))   // B12, -8388608p-43    fmt.Printf("%b\n", 12.9 - mult64(3, 4.3))   // C12, 4503599627370496p-101    fmt.Printf("%b\n", 12.9 - 3*4.3)                                // A14, 4503599627370496p-483    fmt.Printf("%b\n", float32(12.9) - float32(3)*float32(4.3))     // B14, -8388608p-43    fmt.Printf("%b\n", float64(12.9) - float64(3)*float64(4.3))     // C14, 4503599627370496p-101上面代码中的一些事实(bin 形式的一个):A11 行和 C11 行(最后一位数字 - 就在指数之前)之间存在差异。A12 和 C12 行几乎相同(除了指数!!!),在 A14 和 C14 行之间可以观察到相同。问题来了:裸 (naked :)) 数字的计算是如何执行的?(每个 Axx 行中的计算)它们是由编译器执行的吗?如果是,那么为什么它们不同?优化?它们是在与 IEE-754 不同的系统中计算的吗?如果是,为什么会这样?实现更准确的精度是否证明这种方法是合理的?代码已在“go run”和“go build”(go1.0.3)下在 64 位 linux 上进行了测试,也在该站点上进行了测试:http ://tour.golang.org/
查看完整描述

2 回答

?
12345678_0001

TA贡献1802条经验 获得超5个赞

  1. 常数

    • 数字常量代表任意精度的值并且不会溢出。

    • 表示至少 256 位的整数常量。

    • 表示浮点常量,包括复数常量的部分,尾数至少为 256 位,带符号指数至少为 32 位。

  2. 是的,由编译器用于编译时常量。

  3. 是的,它们是不同的:涉及更高的精度。见 1。

  4. 是的,见 1。

  5. 最小化多项浮点常量表达式的浮点错误累积。

  6. 当然是的。实现较低的精度可以成为一个目标吗?运行时浮点运算本质上是不完美的就足够了,不需要从常量表达式中添加更多的不精确性。


查看完整回答
反对 回复 2021-06-21
  • 2 回答
  • 0 关注
  • 246 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信