这是 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个赞
常数:
数字常量代表任意精度的值并且不会溢出。
表示至少 256 位的整数常量。
表示浮点常量,包括复数常量的部分,尾数至少为 256 位,带符号指数至少为 32 位。
是的,由编译器用于编译时常量。
是的,它们是不同的:涉及更高的精度。见 1。
是的,见 1。
最小化多项浮点常量表达式的浮点错误累积。
当然是的。实现较低的精度可以成为一个目标吗?运行时浮点运算本质上是不完美的就足够了,不需要从常量表达式中添加更多的不精确性。
- 2 回答
- 0 关注
- 246 浏览
添加回答
举报
0/150
提交
取消