avatar1 avatar
@{[{user.name}]}
希腊·圣域
since February 1500

JavaScript中关于数字的“坑”及常见的问题

JS中只有一种数字类型: Number

不像其他的编程语言,JS中的数字没有 int, long, float, double等等,所有的数字类型都被存储为64位字节中。

精度 Precision
console.log(999999999999999);  
//打印出:999999999999999

console.log(9999999999999999);  
//打印出10000000000000000

整数型的数字最大可表示15位,超过15位后即变为不精确的数字。

Integers (numbers without a period or exponent notation) are considered accurate up to 15 digits.

console.log(0.11111111111111111)  
//打印出0.11111111111111111 -- 共17位
console.log(0.111111111111111111)  
//打印出0.11111111111111111 -- 共17位

可以看出小数位的最大精度为小数点后17位, 超过17位的则不再精确,注意是不再精确,而不是丢弃, 假如超过17位,0.111111111111111112会输出什么呢,有时会输出0.11111111111111111,有时是0.111111111111111112,即不再精确

小数运算不总是精确的!!!
  0.1 + 0.2 == 0.300000000000000004

这种问题的出现是因为0.1与0.2在计算前会被存储到64位的字节中会有一定的精度损失,或变大或变小,因为损失的精度在小数后很多位,对于实际生产不会造成任何问题,如果两个数字说产生的精度损失不能互相抵消的话,就会产生上面的情况。这个时候如果用于实际生产中可以使用.toFixed(2)来确定小数点后保留2位

还有一个巧妙的办法可以得到精确的 0.1 + 0.2 的结果 0.3, 就是计算前将两个被加数转化为整型,然后在用除法还原:(0.1 * 10 + 0.2 *10)/ 10

永远不要在数字前面加0, 比如05

有一些JS的解释器会将前面带0的数字理解为8进制(octal).

将数字打印/转化为2,8,或16进制

用.toString()方法既可以实现,例如 .toString(2) 为2进制,.toString(16)为16进制。

JS中的无穷 Infinity

用无穷可以计算出JS中支持的最大数字,比如:

var num = 0;  
while(num != Infinity){  
   num++;
}
JS 的NaN,Not a Number

10/'apple' 结果是一个NaN,但是你绝不可以 这样比较 :10/'apple' == NaN 结果永远会是false,正确的做法是isNaN(10/'apple'), 此外10/'apple' == 10/'apple'的结果也永远为false。

如果将NaN用于计算之中,那么结果将永远是NaN。

NaN 与 Infinity 的类型都是 “number”
console.log(typeof NaN); //打印:number  
console.log(typeof Infinity);//打印 number  
Number对象

可以用创造对象的方法初始化数字,比如 var x = new Number(100), 检查x的类型时 typeof x == object, 如果 var x = 100, 那么检查类型时会变成 typeof x == number.

在初始化数字的时候尽量不要用对象Number创建,因为即牺牲性能又会造成意外的结果。比如 x = new Number(100); y = 100;, 当用==比较时结果会是true,但是如果用===比较时结果会返回false。

比较两个不同的Number对象永远会返回false,因为比较的是引用。
var x = new Number(100);  
var y = new Number(100);

x == y; 返回 false,对象不可以比较,或者说x,y引用不同的地址。  

但是如果是

 var x = new Number(100);
 var y = x;

 x == y; 返回 true,两者引用同一个地址。
  02 November, 2016     02 November, 2016