dream6120 2013-08-05 11:13
浏览 60
已采纳

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

}

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
", 3*4.3)                   // A11, 7262054399134925p-49
    fmt.Printf("%b
", mult32(3, 4.3))          // B11, 13526631p-20
    fmt.Printf("%b
", mult64(3, 4.3))          // C11, 7262054399134924p-49

    fmt.Printf("%b
", 12.9 - 3*4.3)            // A12, 4503599627370496p-483
    fmt.Printf("%b
", 12.9 - mult32(3, 4.3))   // B12, -8388608p-43
    fmt.Printf("%b
", 12.9 - mult64(3, 4.3))   // C12, 4503599627370496p-101

    fmt.Printf("%b
", 12.9 - 3*4.3)                                // A14, 4503599627370496p-483
    fmt.Printf("%b
", float32(12.9) - float32(3)*float32(4.3))     // B14, -8388608p-43
    fmt.Printf("%b
", float64(12.9) - float64(3)*float64(4.3))     // C14, 4503599627370496p-101

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

  1. There is difference between line A11 and C11 (last digit - just before the exponent).
  2. Lines A12 and C12 are almost the same (except the exponen!!!), the same can be observed between line A14 and C14.

And here the questions come:

  1. How computations of bare (naked :)) numbers are performed? (computations in every Axx line)
  2. Are they performed by compiler/whatever?
  3. If yes, then why are they different? Optimisation?
  4. Are they computed in some system which differs from IEE-754?
  5. If yes, why so?
  6. Is achieving more accurate precision justifiest such approach?

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/

  • 写回答

2条回答 默认 最新

  • dongzhuo3376 2013-08-05 11:25
    关注
    1. Constants:

      • 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.
    2. Yes, by the compiler for compile time constants.

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

    4. Yes, see 1.

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

    6. 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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度