令人震惊的是,这种情况发生了,我没有解释。由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?考虑二进制它没有意义。
答案 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。
上的维基百科页面突出显示(float / double是base / radix 2):
有限数,可以是基数2(二进制)或基数10(十进制)。每个有限数由三个整数描述:
s =符号(零或一),
c =有效数字(或'系数'),
q =指数。
有限数的数值是
( - 1)^ s×c×b ^ q
其中b是基数(2或10),也称为基数。 例如,如果基数为10,则符号为1(表示负数),有效数字为12345,指数为-3,则数字值为-12.345。
答案 1 :(得分:0)
问题在于,IEEE 754格式中没有使用mantissa * pow(2.0, exponent)
形式的表达式的3.4的精确表示。
0.4本身并不是严格意义上的问题,因为它是以2的幂表示的整数,需要表示,而不仅仅是“十进制”点之后的部分。