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条)

报告相同问题?

悬赏问题

  • ¥15 乌班图ip地址配置及远程SSH
  • ¥15 怎么让点阵屏显示静态爱心,用keiluVision5写出让点阵屏显示静态爱心的代码,越快越好
  • ¥15 PSPICE制作一个加法器
  • ¥15 javaweb项目无法正常跳转
  • ¥15 VMBox虚拟机无法访问
  • ¥15 skd显示找不到头文件
  • ¥15 机器视觉中图片中长度与真实长度的关系
  • ¥15 fastreport table 怎么只让每页的最下面和最顶部有横线
  • ¥15 java 的protected权限 ,问题在注释里
  • ¥15 这个是哪里有问题啊?