群发资讯网

0.1+0.2为什么不等于0.3?我终于和JavaScript的Number和解了

大家好,我是 31 岁、依旧对技术充满好奇心的小米。有一天晚上,我在改一个看似“非常简单”的 JavaScript B



大家好,我是 31 岁、依旧对技术充满好奇心的小米。

有一天晚上,我在改一个看似“非常简单”的 JavaScript Bug:

页面上明明写的是 0.1 + 0.2,结果却显示成了 0.30000000000000004。

那一刻,我突然意识到我们每天都在用的 Number,其实一点都不“简单”。

于是我决定,把 JavaScript 里的 Number,当成一个住在“数字王国”的角色,认真聊一聊它的脾气、边界、怪癖,以及它是如何从“别的类型”变成数字的。

数字王国里,没有“整数”和“小数”的区别

在很多语言里,数字王国是分等级的:

int 是平民

long 是贵族

float、double 是另一套体系

但 JavaScript 不一样。在 JavaScript 的世界里,数字王国只有一个身份:Number:所有数字,都是它

不管你写的是:

它们的类型都是:

没有 int,没有 float,只有 Number。但问题也正是从这里开始的。

浮点值:Number 的“浪漫主义”

1、为什么 0.1 + 0.2 不等于 0.3?

我们先来看一个“经典名场面”:

第一次看到这个结果的新手,通常会怀疑人生。但在 Number 的世界里,这其实是理所当然的。原因只有一句话:

JavaScript 的 Number 使用 IEEE 754 双精度浮点数格式

你可以把它想象成这样一个故事:一个装水的杯子故事,想象你有一个杯子,只能装 二进制的水。

0.1 是十进制世界的水

倒进二进制的杯子里,只能“近似表示”

于是:

0.1 → 一个无限循环的小数

0.2 → 也是一个无限循环的小数

杯子只能装下“接近”的水量,最后一加,就溢出了一点点误差。

2、浮点数的正确比较方式

在真实项目里,我们几乎从不直接比较浮点数是否相等。

正确姿势是:比较误差是否足够小。

这里的 Number.EPSILON,你可以把它理解为:

JavaScript 能接受的最小误差单位

值的范围:Number 也有“体力极限”

再强的王国,也有疆界。Number 的世界,同样有最大值和最小值。

1、Number 能表示多大?

我们可以用一张表来理解它:

2、超出范围会发生什么?

Number 就像一个老实人:

超过能力上限 → Infinity

小到无法表示 → 直接归零

3、安全整数:你以为整数就安全了吗?

这是一个非常容易被忽略的点。

所谓“安全整数”,指的是:在这个范围内,整数可以被精确表示

超过这个范围:

数字王国的会计已经算不清账了。所以:

金额

计数

ID

千万不要随便依赖超大整数的精度

NaN:数字王国里的“失踪人口”

如果说 Infinity 是“力量失控”,那 NaN 就是“逻辑失踪”。

1、什么是 NaN?

NaN 的全名是:Not a Number

但它的类型却是:

是不是有点反直觉?

2、NaN 从哪里来?

你可以理解为:数字王国拒绝回答的问题

3、NaN 的最大怪癖:它不等于自己

在整个 JavaScript 世界里,只有 NaN 会否认自己。

正确判断方式只有一个:

注意区分:

NaN 常见行为总结表

NaN 一旦出现,就像“病毒”,会在计算中一路传播。

数值转换:Number 的“变形术”

在 JavaScript 里,Number 最大的能力之一是:它可以从“别的类型”变成数字,但不同方式,性格完全不同。

1、Number():最正统的方式

它遵循的是整体必须是一个合法数字。

2、parseInt / parseFloat:更像“街头翻译官”

特点是:

从左到右解析

遇到非数字就停

3、隐式转换:最容易踩坑的魔法

原因只有一个:+ 既是加法,也是字符串拼接

4、数值转换方式对比表

总结:尊重 Number,才能不被它“坑”

回到最开始那个 0.1 + 0.2 的问题。那不是 JavaScript 不靠谱,而是 Number 从一开始就没承诺过“完美精度”。

Number 就像一个能力很强、但性格真实、有边界、有怪癖的老朋友。

你越了解它:

浮点误差

安全整数

NaN 行为

转换规则

你就越不会在深夜 Debug 时怀疑人生。

END

如果你觉得这篇文章对你理解 Number 有帮助,欢迎点赞、转发,让更多人认识这个不简单的 Number。

我是小米,一个喜欢分享技术的31岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货!