dpir3950 2019-03-09 16:21
浏览 41

为什么浮点加法不精确? [重复]

This question already has an answer here:

I found the following strange behavior. Adding some floats result in "random" accuracy.

so first I run go version go1.12 darwin/amd64 on macOS Mojave (10.14.3) with Intel i7 2,6 Ghz

the behavior occur in the following Example:

func TestFloatingAddition(t *testing.T) {
    f1 := float64(5)
    f2 := float64(12.1)
    f5 := float64(-12.1)
    f3 := f1 + f2 // 17.1
    f4 := f3 + f5 // 5.000000000000002
    if f4 != f1 {
        t.Fatal("addition is not reversable")
    }
}

Can someone explain to me why f4 takes on this strange value, and what can I do to fix it?

</div>
  • 写回答

2条回答 默认 最新

  • doufuhao0566 2019-03-09 16:48
    关注

    This is not a problem with Go-lang (or C, C++, Java, Python, Ruby), or any modern language which uses IEEE-754 floating point to represent floating point numbers. There are numbers that are not exactly representable using binary or decimal based floating point storage formats.

    Floating point numbers are represented using IEEE-754 floating point as three parts, a sign bit, mantissa, and exponent (using exponent bias, offset by 127, 1023, etc, subtracted from exponent). The mantissa is encoded as a binary sequence, and essentially left/right shifted exponent bits to form binary fractions. And with binary fractions lies the problem.

    In the same way that the fraction 1/3 is 'relatively prime' in base-10, and cannot be exactly represented in decimal, certain numbers cannot be expressed exactly using binary fractions. Decimal numbers are 'relatively prime' to binary numbers, since 10=2*5 has the factor 5. You cannot express 1/5 exactly as binary fraction, just as the fractions 1/3, 1/7, 1/11, 1/13, 1/17, etc (notice the pattern of prime numbers here?) cannot be expressed exactly in either decimal or binary fractions. The internal representation will always approximate these numbers, and some string conversion libraries use conversions to reduce the approximation error.

    What can you do? If you are using only linear arithmetic operators, you could use fixed-point decimal libraries (that is what [shudder] Cobol does).

    Some libraries store fractional numbers as ratios of two whole numbers, but this does not solve the problem when you introduce functions such as square root which can produce irrational numbers.

    评论

报告相同问题?

悬赏问题

  • ¥15 cgictest.cgi文件无法访问
  • ¥20 删除和修改功能无法调用
  • ¥15 kafka topic 所有分副本数修改
  • ¥15 小程序中fit格式等运动数据文件怎样实现可视化?(包含心率信息))
  • ¥15 如何利用mmdetection3d中的get_flops.py文件计算fcos3d方法的flops?
  • ¥40 串口调试助手打开串口后,keil5的代码就停止了
  • ¥15 电脑最近经常蓝屏,求大家看看哪的问题
  • ¥60 高价有偿求java辅导。工程量较大,价格你定,联系确定辅导后将采纳你的答案。希望能给出完整详细代码,并能解释回答我关于代码的疑问疑问,代码要求如下,联系我会发文档
  • ¥50 C++五子棋AI程序编写
  • ¥30 求安卓设备利用一个typeC接口,同时实现向pc一边投屏一边上传数据的解决方案。