如何将Javascript号存储在内存中

时间:2012-04-10 05:00:48

标签: javascript numbers

首先,我们看到以下代码:

result = 0.1 + 0.2;     
alert(result===0.3);// false
result=100.1+100.2;
alert(result===200.3);//true

我相信0.1100.1(100 + 0.1)在内存中的存储类似,因为两者中的小数都是.1

那么,为什么加法的结果不同?

3 个答案:

答案 0 :(得分:6)

它们在内存中的存储方式不同:http://steve.hollasch.net/cgindex/coding/ieeefloat.html

0.1二进制:

0.1 * 2 = 0 + 0.2
0.2 * 2 = 0 + 0.4
0.4 * 2 = 0 + 0.8
0.8 * 2 = 1 + 0.6
0.6 * 2 = 1 + 0.2
0.2 * 2 = 0 + 0.4
0.4 * 2 = 0 + 0.8
0.8 * 2 = 1 + 0.6
0.6 * 2 = 1 + 0.2

如您所见,在重复0.2后,整个模式(0011)将不断重复,因此0.10.0001100110011001100110011..。永远重复

为了表示在23位尾数中我们必须向左移动直到我们在小数点之前有1(在将位移到4位并移除小数点前的1之后我们有100110011...)并且然后在第23位进行回合,得到:10011001100110011001101

由于我们移动了4个位置,我们的指数为127-4(127是32位偏差)。 8位二进制的123是01111011,剩下的就是符号位,我们知道它是0,因为0.1是正数。因此,32位二进制数的每个分量都是:

签字:0
指数:01111011
尾数:10011001100110011001101

0.1在浮点数中表示为00111101110011001100110011001101

转换回来我们必须将其拆分,然后将指数转换回十进制整数(123)。我们将尾数(假设前面的1)向右移动(127 - 123 = 4)次并获得:0.00011001100110011001101101然后我们将其转换回小数:

0*1/2 + 0*1/4 + 0*1/8 + 1/16 + 1/32 + 0*1/64 + 0*1/128 + 1/256 + 1/512 + 
0 + 1/4096 + 1/8192 + 0 + 1/65536 + 1/131072 + 0 + 1/1048576 + 1/2097152 + 
0 + 1/16777216 + 1/33554432 + 0 + 1/134217728

如果你进行数学运算会给你一些接近0.100000001的东西,而不是0.1。那是因为我们在第23位进行了舍入。 0.1不能以二进制形式存储,因为它会永远重复,因此在第23位之后我们就会出现不准确的情况。当你对一个数字进行算术运算时,这些不准确性会被执行,并且错误会变得更大。

如果你用100.1做同样的事情,你会得到:

1100100.0001100110011001100 ...永远重复:

右移6次并将小数点前的1移至第23位:10010000011001100110011

指数为127 + 6 = 133(1000 0101)

Sign再次为0,所以你有:

01000010110010000011001100110011

答案 1 :(得分:0)

除了Paul P.R.O的回答

这不仅仅是javascript的问题。在C#中,double表现出相同的行为

double a = 0.1, b = 0.2;
Console.WriteLine((a + b)==0.3); //Prints False

因此,建议在c#中使用decimal作为精度。对于javascript,您应该使用.toFixed来处理货币操作。有关javascript内部数字的详细信息,请查看http://www.hunlock.com/blogs/The_Complete_Javascript_Number_Reference#quickIDX0

答案 2 :(得分:0)

这是IEEE 754 wikipedia实施结果。没有办法显示每个浮点数,它在IEEE 754标准之后以每种语言出现。此代码段将以任何语言显示相同的结果:

var sum = 0.0;
for (var i = 0; i < 10; i++ )
{
    sum += 0.1;
}
// sum = 0.9999999999999999

0.1正是其中一个没有精确表示的数字wikipedia

C#有一个特殊的十进制MSDN类型,适用于财务和货币计算,这是一种结构。