go中的浮点运算

这是 go 中的示例代码:


package main


import "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/


蝴蝶刀刀
浏览 247回答 2
2回答

12345678_0001

常数:数字常量代表任意精度的值并且不会溢出。表示至少 256 位的整数常量。表示浮点常量,包括复数常量的部分,尾数至少为 256 位,带符号指数至少为 32 位。是的,由编译器用于编译时常量。是的,它们是不同的:涉及更高的精度。见 1。是的,见 1。最小化多项浮点常量表达式的浮点错误累积。当然是的。实现较低的精度可以成为一个目标吗?运行时浮点运算本质上是不完美的就足够了,不需要从常量表达式中添加更多的不精确性。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go