这是因为javascript数字是64位浮点数。
浮点数有2个部分 - 小数部分定义数字的“值”,指数部分定义数字应该移动到小数点的左边或右边多远。
为了说明这一点的工作,我会使用的十进制基础,而不是二进制的虚浮点数格式如何:
让我们来定义我们想象的格式为8个字符的花车 - 这是数必须存储内8个字符。让分区我们的格式,有6个字符作为小数部分和2个字符作为指数:
_ _ _ _ _ _ _ _
|_ _|_ _ _ _ _ _| <--- 8 char float
exponent fractional
为了便于讨论,让我们创造一个语法描述格式:
exponent,fractional
因此,例如, ,号码128
可以存储为0,128
,PI可以存储为-5,314159
(小数点左移5位)。
上面的PI例子是程序员第一次遇到浮点数 - 他们需要使用分数而不是简单的整数。但是浮点格式还有另外一个特点 - 它可以存储大于分配小数部分空间的数字!
例如,如果我们想要以我们想象的8char浮点格式存储数字987654321会怎么样?它超过6个字符!那么,我们会这样做:2,9876543
。也就是说,我们存储最重要的数字并将小数点右移2个空格。
如果我们尝试读取该数字,那么得到的是987654300。我们失去了最低有效位数!嗯..听起来很熟悉。
在javascript的情况下,格式是IEEE 754 64位二进制浮点。它有52位分配给小数部分(如果包含符号位,则为53)。这意味着对于高达52位的数字,它的行为就像一个整数。任何更大的,它将开始牺牲最不重要的位(不是数字,位,所以舍入可能对我们人类看起来很奇怪)。
详情请参见在64位浮点数是如何工作的这个维基百科文章:http://en.wikipedia.org/wiki/Double_precision_floating-point_format
JavaScript的商店*每*号的为内部的浮动,包括整数。你只是失去了精确性。 – Blender
有没有办法避免失去精确度? Java中是否有像BigInteger这样的东西,或者更高精度的东西? –
Google“bigint javascript”。没有内置的东西。 – Blender