编写数字的更多方法

十六进制,二进制和八进制数字

对于不同的数字系统:

  1. 十六进制 数字在 JavaScript 中被广泛用于表示颜色,编码字符以及其他许多东西。所以自然地,有一种较短的写方法:0x,然后是数字。
  2. 二进制和八进制数字系统很少使用,但也支持使用 0b 和 0o 前缀:
  3. 只有这三种进制支持这种写法。对于其他进制,应该使用函数 parseInt。

toString(base):变成字符串,并可以指定进制

方法 num.toString(base) 返回在给定 base 进制数字系统中 num 的字符串表示形式。

  1. base 的范围可以从 2 到 36。默认情况下是 10。

Math

  1. 舍入(rounding)是使用数字时最常用的操作之一。
  2. 以上这些函数涵盖了处理数字小数部分的所有可能方法。但是,如果我们想将数字舍入到小数点后 n 位,该怎么办?有两种方式可以实现这个需求:
  3.         
                let num = 12.34;
                alert( num.toFixed(5) ); // "12.34000",在结尾添加了 0,以达到小数点后五位
            
        

    我们可以使用一元加号或 Number() 调用,将其转换为数字,例如 + num.toFixed(5)。

不精确的计算

  1. 一个数字以其二进制的形式存储在内存中,一个 1 和 0 的序列。但是在十进制数字系统中看起来很简单的 0.1,0.2 这样的小数,实际上在二进制形式中是无限循环小数。
  2. 在十进制数字系统中,可以保证以 10 的整数次幂作为除数能够正常工作,但是以 3 作为除数则不能。也是同样的原因,在二进制数字系统中,可以保证以 2 的整数次幂作为除数时能够正常工作,但 1/10 就变成了一个无限循环的二进制小数。
  3. 使用二进制数字系统无法 精确 存储 0.1 或 0.2,就像没有办法将三分之一存储为十进制小数一样。
  4. 不仅仅是 JavaScript。许多其他编程语言也存在同样的问题。PHP,Java,C,Perl,Ruby 给出的也是完全相同的结果,因为它们基于的是相同的数字格式。
  5. 我们能解决这个问题吗?当然,最可靠的方法是借助方法 toFixed(n) 对结果进行舍入:
  6.         
                let sum = 0.1 + 0.2;
                alert( sum.toFixed(2) ); // 0.30
            
        
  7. 请注意,toFixed 总是返回一个字符串。它确保小数点后有 2 位数字。如果我们有一个电子购物网站,并需要显示 ¥ 0.30,这实际上很方便。对于其他情况,我们可以使用一元加号将其强制转换为一个数字:
  8.         
                let sum = 0.1 + 0.2;
                alert( +sum.toFixed(2) ); // 0.3
            
        
  9. 我们可以将数字临时乘以 100(或更大的数字),将其转换为整数,进行数学运算,然后再除回。当我们使用整数进行数学运算时,误差会有所减少,但仍然可以在除法中得到:
  10.         
                alert( (0.1 * 10 + 0.2 * 10) / 10 ); // 0.3
                alert( (0.28 * 100 + 0.14 * 100) / 100); // 0.4200000000000001
            
        
  11. 因此,乘/除法可以减少误差,但不能完全消除误差。

测试:isFinite 和 isNaN

  1. 还记得这两个特殊的数值吗?
  2. 它们属于 number 类型,但不是“普通”数字,因此,这里有用于检查它们的特殊函数:

  3. isNaN(value) 将其参数转换为数字,然后测试它是否为 NaN:
  4. isFinite(value) 将其参数转换为数字,如果是常规数字而不是 NaN/Infinity/-Infinity,则返回 true:
  5. 与 Object.is 进行比较:有一个特殊的内建方法 Object.is,它类似于 === 一样对值进行比较,但它对于两种边缘情况更可靠

parseInt 和 parseFloat

使用 parseInt/parseFloat 进行“软”转换,它从字符串中读取数字,然后返回在发生 error 前可以读取到的值。

  1. 使用加号 + 或 Number() 的数字转换是严格的。如果一个值不完全是一个数字,就会失败。唯一的例外是字符串开头或结尾的空格,因为它们会被忽略。
  2. 从字符串中“读取”数字,直到无法读取为止。如果发生 error,则返回收集到的数字。函数 parseInt 返回一个整数,而 parseFloat 返回一个浮点数。
  3.         
            alert( parseInt('100px') ); // 100
            alert( parseFloat('12.5em') ); // 12.5
            alert( parseInt('12.3') ); // 12,只有整数部分被返回了
            alert( parseFloat('12.3.4') ); // 12.3,在第二个点出停止了读取
            
        
  4. 某些情况下,parseInt/parseFloat 会返回 NaN。当没有数字可读时会发生这种情况:alert( parseInt('a123') ); // NaN,第一个符号停止了读取
  5. parseInt(str, radix) 的第二个参数:可指定数字系统的基数,因此 parseInt 还可以解析十六进制数字、二进制数字等的字符串
  6.         
            alert( parseInt('0xff', 16) ); // 255
            alert( parseInt('ff', 16) ); // 255,没有 0x 仍然有效
            alert( parseInt('2n9c', 36) ); // 123456
            
        

其他数学函数

JavaScript 有一个内建的 Math 对象,它包含了一个小型的数学函数和常量库。