原来 js 中的数字都是浮点数呀

小知识,大挑战!本文正在参与“ 程序员必备小知识 ”创作活动

JavaScript 中的浮点数

大多数编程语言都有几种数值型数据类型,但是 JavaScript 却只有一种。你可以使用 typeof 运算符查看数字的类型。不管是整数还是浮点数,JavaScript 都将它们简单地归类为数字。

 typeof 10 // number
 typeof 10.1 // number
 typeof -10.1 // number 

事实上,JavaScript中所有的数字都是双精度浮点数。这是由IEE 754标准制定的64位编码数字—即 “doubles” 。

那么 JavaScript 是如何表达整数的呢?

请先记住一个概念 : 双精度浮点数能完美地表示高达53位精度的整数,范围大小为 -2^53----2^53 的所有整数都是有效的双精度浮点数

因此,尽管 JavaScript中缺少明显的整数类型,但是完全可以进行整数运算。

大多数的算术运算符可以使用整数、实数或两者的组合进行计算。

 console.log(0.1 * 1.9);   // 0.19;
 console.log(-10 + 11);    // 1
 console.log(20 - 10);     // 10
 console.log(5 / 10);      // 0.5
 console.log(49 / 7);      // 7

然而位算术运算符比较特殊。JavaScript不会直接将操作数作为浮点数进行运算,而是会将其隐式地转换为32位整数后进行运算(确切地说,它们被转换为32位大端(big-endian) 的 2 补码表示的整数)

 console.log(8 | 1); //9

看似简单的表达式实际上需要几个步骤来完成运算

如前文所述,JavaScript 的数字都是双精度浮点数。同时也可以表示为 32 位整数,即 32 位 0、1的序列。

整数 8 为 32 位二进制序列如下

00000000000000000000000000001000

我们也可以用 JavaScript 中数字类型的 toString 方法来查看

 // 转成二进制
 (8).toString(2) // "1000"

整数1表示为32位二进制如下所示: 00000000000000000000000000000001

然后按照相同位只要一个为1即为1 的运算法则,那么结果就是

00000000000000000000000000001001

其结果就是

 // 将 1001 看成二进制,返回十进制数
 ParseInt("1001",2) // 9

所有位运算符的工作方式都是相同的。其操作步骤为 :

  • 将操作数转换为 32 位整数
  • 使用整数位模式进行运算
  • 将结果转换为标准的 JavaScript 浮点数
  • 一般情况下,JavaScript 引擎需要做一些额外的工作来进行折现转换。

    因为数字是以浮点数存储的,必须将其转为整数,然后再转回浮点数。

    然后我们在进行浮点数的运算的时候会发现一些不正确的结果

     0.1 + 0.2 // 0.30000000000000004
    

    尽管64位的精度已经相当高了,但是双精度浮点数也只能表示一组有限的数字,而不能表示所有的实数集。浮点运算只能产生近似的结果,四舍五入到最接近的可表示的实数。

    浮点数权衡了精度和性能。当我们关系精度的时候,要小心浮点数的局限性。一个有效的解决办法就是尽可能地采用整数值运算,因为整数在表示时不需要舍入。

  • JavaScript 的数字都是双精度的浮点数。
  • JavaScript中的整数仅仅是双精度浮点数的一个子集,而不是一个单独的数据类型。
  • 位运算符将数字视为 32 位的有符号整数。
  • 分类:
    前端
    标签: