为什么3.4不能完全用'double`数据类型表示?

时间:2014-11-14 00:20:25

标签: c++

令人震惊的是,这种情况发生了,我没有解释。由visual studio创建的简单控制台应用程序:

#include <stdlib.h>
#include <crtdbg.h>

#include "stdafx.h"
#include "ConsoleApplication.h"

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
    double a;
    a = 3.4;

    return 0; // <=======  Debug break point set here
}

a的值是3.3999999999999999而不是3.4。对于大多数程序员来说这不是问题,但为什么数字3.4不能完全存储为double?考虑二进制它没有意义。

2 个答案:

答案 0 :(得分:6)

因此,为了在二进制表示中表示0.4,您可以查看两个幂的分数。

最初,你说,

    1/2 = 0.5.   Too big.         -> 0/2
    1/4 = 0.25.  Great.           -> 0/2 + 1/4       => 0.25
    1/8 = 0.125. We can add this. -> 0/2 + 1/4 + 1/8 => 0.375.

这继续(1 / 16,1 / 32太大而不能添加,但是1/64是好的),我们得到重复模式(以总和分数的二进制表示)

0.011001100110011001100....

其中越来越接近0.4,但从未达到过它。

有关更简单的解释或示例,请参阅this python link

链接到IEEE Floating Point

上的维基百科页面

突出显示(float / double是base / radix 2):

  

有限数,可以是基数2(二进制)或基数10(十进制)。每个有限数由三个整数描述:

     

s =符号(零或一),

     

c =有效数字(或'系数'),

     

q =指数。

     

有限数的数值是

     

( - 1)^ s×c×b ^ q

     

其中b是基数(2或10),也称为基数。   例如,如果基数为10,则符号为1(表示负数),有效数字为12345,指数为-3,则数字值为-12.345。

链接到IEEE standard

答案 1 :(得分:0)

问题在于,IEEE 754格式中没有使用mantissa * pow(2.0, exponent)形式的表达式的3.4的精确表示。

0.4本身并不是严格意义上的问题,因为它是以2的幂表示的整数,需要表示,而不仅仅是“十进制”点之后的部分。