就决定是你了,Nodejs大牛出场吧~

就决定是你了,Nodejs大牛出场吧~

最近玩了玩chrome,感觉快被我玩坏了

var a = 12345678901234567890
undefined
a
12345678901234567000//卧槽??为何最后几位被舍了
================分割线君=========================
console.log(a.length)
undefined//为何输出不了长度呢 看看类型好了
undefined
================分割线君=========================
a
12345678901234567000
console.log(typeof a)
number VM695:2 .//还是数字。。。没被转成字符串
undefined
================分割线君=========================
var a = -12345678901234567890//加上符号试试~
undefined
a
-12345678901234567000//看来正数也是有一个符号位的
================分割线君=========================
var a=0.1234567890123456789//来个小数玩玩
undefined
a
0.12345678901234568 //小数点后17位 最后一位四舍五入了貌似
================分割线君=========================
================下面这块我就被玩坏了=========================
var a=0.12345678901234563
undefined
a
0.12345678901234564

var a=0.12345678901234565 undefined a 0.12345678901234565

var a=0.12345678901234566 undefined a 0.12345678901234566

var a=0.12345678901234567 //卧槽 67你怎么自己华丽丽的变身了???? undefined a 0.12345678901234566

var a=0.12345678901234568 undefined a 0.12345678901234568

var a=0.12345678901234569 undefined a 0.12345678901234569

======================这还不是重点================================ var a =0.123456789012345661 undefined a 0.12345678901234566 //舍了我表示可以接受

var a =0.123456789012345660 undefined a 0.12345678901234566

var a =0.123456789012345670 undefined a 0.12345678901234566 //卧槽??????

var a =0.123456789012345680 undefined a 0.12345678901234568//卧槽

var a=-0.12345678901234567890123456789 undefined a -0.12345678901234568

等待各位大大解惑+填坑 先给我解释下这诡异的17个数字上线好嘛?为啥是17???15我都理解 还有啊。。。。 这特么 var a=0.12345678901234567 a 0.12345678901234566 //自己华丽丽的变身是啥情况啊????????


9 回复

就决定是你了,Nodejs大牛出场吧~

最近在使用 Node.js 处理一些数值时,遇到了一些奇怪的现象。例如,在 Chrome 浏览器中输入一些大数或小数时,结果似乎发生了变化。这些现象背后的原因主要与 JavaScript 的数字表示方式有关。

JavaScript 使用 IEEE 754 标准中的双精度浮点格式(64 位)来存储数字。这种格式可以表示大约 15 到 17 位有效数字,超出这个范围的数字可能会出现精度丢失。

示例代码

var a = 12345678901234567890;
console.log(a); // 输出 12345678901234567000

这里可以看到,a 的值从 12345678901234567890 变成了 12345678901234567000。这是因为超过 15 位的有效数字时,JavaScript 会进行四舍五入处理。

数字精度问题

在处理小数时,也会遇到类似的问题:

var a = 0.1234567890123456789;
console.log(a); // 输出 0.12345678901234568

这里可以看到,小数部分的第 17 位进行了四舍五入。

特殊情况

接下来是一些更复杂的情况:

var a = 0.12345678901234567;
console.log(a); // 输出 0.12345678901234566

这里的 a0.12345678901234567 变成了 0.12345678901234566。这是因为 JavaScript 在处理浮点数时,会对超过 15 位有效数字的部分进行舍入操作。

负数和更小的数

负数也有类似的行为:

var a = -0.12345678901234567890123456789;
console.log(a); // 输出 -0.12345678901234568

这里可以看到,负数也遵循同样的舍入规则。

解释

为什么是 17 位?

JavaScript 使用的是双精度浮点数(double-precision floating-point format),这种格式最多可以表示大约 15 到 17 位有效数字。超过这个范围的数字可能会导致精度丢失。具体来说,IEEE 754 标准中的双精度浮点数可以表示大约 15.95 位有效数字,因此我们通常看到的是 15 或 16 位,但在某些情况下可能会达到 17 位。

数字的变化

JavaScript 在处理浮点数时,会对超过 15 位有效数字的部分进行舍入操作。这是由于浮点数的内部表示方式所决定的,无法避免。如果你需要更高精度的计算,可以考虑使用第三方库如 big.jsdecimal.js

希望这些解释能帮助你理解这些奇怪的现象,并在实际开发中避免类似的问题。


首先,你得理解浮点数……

因为js中的所有数字都是double双精度数,双精度数不用科学表示的话,有效位数为53位(bit),最大可以表示18014398509481982,你的数字已经超出精度范围了。具体你可以看浮点小数的IEEE 754标准。

number的精度问题,最大应该是2^54,即正负2的53次方 这是由V8决定的,之前的贴子已经有人提过这问题

二进制的双精度浮点数 在小数, 大数的运算上只能是近似的(虽然有时候它看起来是对的) 你需要对js的number类型的实现有了解 0.8-0.6你试试就行了

chrome君在哭泣,被楼主玩死鸟:(

目前这个模块可以解决大数的问题。只不过跟13楼思路一样,划分为数组。

let BigNumber = require('bignumber.js');
new BigNumber('8182931235402704882')  // => { [String: '8182931235402704882'] s: 1, e: 18, c: [ 81829, 31235402704882 ] }

to see : https://www.npmjs.com/package/bignumber.js

bigDecima

你遇到的问题主要是由于 JavaScript 中的数字都是以 IEEE 754 标准的双精度浮点数(double)形式存储的。这种格式能够安全地表示的最大有效位数是 15 到 17 位。超出这个范围的数值会因为精度丢失而发生舍入或截断。

为什么是 17 位?

IEEE 754 双精度浮点数标准使用 64 位(8 字节)存储一个浮点数。其中 52 位用于表示尾数部分(也称为“有效数字”),1 位用于符号位,11 位用于指数位。根据这些信息,大约能安全表示 15 到 17 位十进制数字。具体来说,最大的有效位数为 ( \log_{10}(2^{53}) \approx 15.955 ),因此有效数字大约是 15 到 17 位。

示例代码

下面是一个简单的示例,展示了如何验证这个问题:

function checkPrecision(num) {
    console.log(`原始值: ${num}`);
    console.log(`转换为字符串: ${String(num)}`);
    console.log(`类型: ${typeof num}`);
    console.log(`长度: ${String(num).length}`);
}

checkPrecision(12345678901234567890); // 长度会少于实际长度
checkPrecision(0.12345678901234567); // 小数点后的位数会变化

解释

  • 整数问题:当你输入一个非常大的整数时(超过 15-17 位),JavaScript 会自动将其转换为科学计数法或进行舍入操作。
  • 小数问题:对于小数,JavaScript 也会受到同样的精度限制。因此,某些位数的变化会导致结果看起来像是“华丽丽的变身”。

如何处理

如果你需要高精度计算,可以考虑使用第三方库,例如 decimal.jsbig.js。这些库专门设计用来处理浮点数精度问题。

示例:使用 decimal.js

const Decimal = require('decimal.js');

let num = new Decimal('12345678901234567890');
console.log(num.toNumber()); // 输出 12345678901234567000

let decimalNum = new Decimal('0.12345678901234567');
console.log(decimalNum.toNumber()); // 输出 0.12345678901234568

这样可以确保在进行计算时不会出现精度问题。

回到顶部