【前端冷知识】你知道+0与-0的区别吗?

JavaScript的数值Number用64位的浮点数表示,首位是符号位,然后是52位的整数位和11位的小数位。如果符号位为1,其他各位均为0,那么这个数值会被表示成“-0”。

所以JavaScript的“0”值有两个,+0和-0。

 
  

const num = -0;

console.log(num); // -0

我们可以用二进制位构造出-0来:

 
  

// 首先创建一个8位的ArrayBuffer

const buffer = new ArrayBuffer(8);

// 创建DataView对象操作buffer

const dataView = new DataView(buffer);


// 将第1个字节设置为0x80,即最高位为1

dataView.setUint8(0, 0x80);


// 将buffer内容当做Float64类型返回

console.log(dataView.getFloat64(0)); // -0

在一般的运算中,我们也有可能产生-0值,比如运算时将-Infinity作为分母,负数除法超过最小可表示数等等:

 
  

console.log(1 / -Infinity); // -0

console.log(-1 / Infinity); // -0

console.log(-Number.MIN_VALUE / 2); // -0

console.log(-1e-1000); // -0

一般情况下-0视同于0,运算并没有什么问题:

 
  

console.log(-0 === 0); // true


const num = -0;

if(!num) { // !num 为 true

  // do sth.

}

除非在分母中有-0存在,恰好又要判断符号的时候,可能会出问题:

 
  

const num = -0;


console.log(1 / num > 0); // false

console.log(Math.sign(1 / num)); // -1

所以如果你知道分母中可能出现0的时候,就要小心-0。

-0也有好处,比如我们可以利用-0来表示状态,比如我们在寻路的时候,把地图的障碍物用1表示,空地用0表示,那么我们就可以把未搜索过的用-1和-0表示,这样也挺方便的。

另外比如我们要存mousemove的坐标位置,那么当鼠标移动出检测范围的时候,可以把mousePosition设为-0来表示当前鼠标不在范围内。

如果要使用-0,我们就得区分它与0。

num === -0是不行的,因为0 === -0也会返回true。

实际上在ES2015中提供了Object.is方法,可以判断-0.

?? 【冷知识】Object.is(value1, value2) 比较两个值是否相同。它与=== 的区别是,Object.is(-0, 0)返回false,Object.is(NaN, NaN)返回true。

如果在早期的JavaScript版本中,我们也可以利用1/-0为-Infinity的特点来判断:

 
  

function isNegativeZero(num) {

  return num === 0 && (1 / num < 0);

}

或者我们可以写一个Object.is的polyfill:

 
  

if (!Object.is) {

  Object.is = function(x, y) {

    // SameValue algorithm

    if (=== y) { // Steps 1-5, 7-10

      // Steps 6.b-6.e: +0 != -0

      return x !== 0 || 1 / x === 1 / y;

    } else {

      // Step 6.a: NaN == NaN

      return x !== x && y !== y;

    }

  };

}

好了,关于-0的问题,你还有什么想法,欢迎在issue中讨论。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值