Go中的浮点运算 [英] floating point operations in go

查看:231
本文介绍了Go中的浮点运算的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是go中的示例代码:

Here's the sample code in 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的输出是相同的.

Results differences between lines A1, B1 and C1 are understandable. However, starting from A2 to C2 magic comes. Result from neither of B2 nor C2 matches the result from A2 line. The same is true for lines x2 (x = A, B or C) - but the outputs of x2 and x4 are the same.

请确保我们以二进制格式打印结果.

Just to be sure let's print the results in the binary form.

    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形式中的一个):

Some facts from the code above (one in the bin form):

  1. A11行和C11行之间存在差异(最后一位-指数之前).
  2. A12和C12行几乎相同(除了指数!!!),A14和C14行之间可以看到相同的结果.

问题来了:

  1. 如何执行裸(裸:)数字? (每个Axx行中的计算)
  2. 它们是由编译器执行的吗?
  3. 如果是,那么为什么它们不同?优化?
  4. 它们是否在不同于IEE-754的某些系统中计算?
  5. 如果是,为什么呢?
  6. 实现这种方法是否需要更精确的精度?

代码已在64位Linux上的运行"和构建"(go1.0.3)下以及该站点上进行了测试: http://tour.golang.org/

Code has been tested on 64bit linux under both "go run" and "go build" (go1.0.3), and also on that site: http://tour.golang.org/

推荐答案

  1. 常量:

  • 数字常量表示任意精度的值,不会溢出.
  • 代表至少256位的整数常量.
  • 表示浮点常数,包括复数常数的部分,尾数至少为256位,带符号的指数至少为32位.
  • Numeric constants represent values of arbitrary precision and do not overflow.
  • Represent integer constants with at least 256 bits.
  • Represent floating-point constants, including the parts of a complex constant, with a mantissa of at least 256 bits and a signed exponent of at least 32 bits.

  • 是的,由编译器编译时间常数.

  • Yes, by the compiler for compile time constants.

    是的,它们是不同的:涉及更多的精度.参见1.

    Yes, they're different: More precision is involved. See 1.

    是,请参阅1.

    要最大程度地减少多项浮点常量表达式的浮点错误累积.

    To minimize accumulation of floating point errors for multi-term floating point constant expressions.

    当然可以.达到精度可以成为目标吗?运行时浮点运算本质上是不完美的,这就不需要在常量表达式中增加更多的不精确性.

    Of course yes. Can achieving lower precision be ever a goal? It's enough that run-time floating point operations are intrinsically imperfect, no need to add more imprecision from constant expressions.

    这篇关于Go中的浮点运算的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆