什么是 Javascript 中的 32 位整数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/47600096/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 07:30:06  来源:igfitidea点击:

What is 32-bit integer in Javascript?

javascriptinteger

提问by Iggy

I was doing some coding challenge and encountered something I am not too familiar with. I am more curious to learn what it is and why it is there.

我正在做一些编码挑战,遇到了一些我不太熟悉的东西。我更想知道它是什么以及它为什么在那里。

The prompt it pretty straightforward: Given a 32-bit signed integer, reverse digits of an integer.

提示很简单: Given a 32-bit signed integer, reverse digits of an integer.

Example:
Input: -123
Output: -321

Example:    
Input: 120
Output: 21

Assume we are dealing with an environment which could only hold integers within the 32-bit signed integer range. For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows.

I came up with this.

我想出了这个。

var reverse = function(x) {
    var isNegative = false;
    if(x < 0){
        isNegative = true;
        x *= -1;
    };
    var reverseX = parseInt(String(x).split('').reverse((a,b) => a - b).join(''));
    if(reverseX > Math.pow(2,32)){
      return 0;
    }
    if(isNegative){
        return -1 * reverseX
    } else {
        return reverseX;
    }
};

However, I am stumped with some of the failing tests:

但是,我对一些失败的测试感到困惑:

Input:
1563847412
Output:
2147483651
Expected: 0

To my understanding, 32 bit integer is 2^32. What is its significance in JS and what happen if I started going over? (2^32 + 1)

据我了解,32 位整数是 2^32。它在 JS 中的重要性是什么?如果我开始复习会发生什么?( 2^32 + 1)

My second question, if I may ask two, is I "anticipated" if value of reverseXexceeds 2^32, but it is still failing the test.

我的第二个问题,如果我可以问两个,如果 的值reverseX超过 2^32,我是否“预期” ,但它仍然没有通过测试。

   if(reverseX > Math.pow(2,32)){
      return 0;
    }

How can I appropriately return 0when I exceeded 32-bit integer?

0当我超过 32 位整数时,如何适当地返回?

回答by trincot

The upper bound of a signedinteger is not 232- 1, but 231- 1, since the first bit is the sign bit.

符号整数的上限不是 2 32- 1,而是 2 31- 1,因为第一位是符号位。

If you make that comparison, you'll see your test gives the right result.

如果您进行比较,您会看到您的测试给出了正确的结果。

Be aware that JavaScript uses IEEE-754 floating pointrepresentation for numbers, even when they are integers. But the precision of floating point is more than enough to perform exact calculations on 32-bit integers. As you realised, you'll need to make the necessary test to detect 32-bit overflow.

请注意,JavaScript对数字使用IEEE-754 浮点表示,即使它们是整数。但是浮点的精度足以对 32 位整数执行精确计算。正如您所意识到的,您需要进行必要的测试来检测 32 位溢出。

Some notes about your code: it passes an argument to the Array#reversemethod, which is a method that does not take an argument. Here is how I would write it -- see comments in code:

关于你的代码的一些注意事项:它向Array#reverse方法传递一个参数,这是一个不带参数的方法。这是我将如何编写它 - 请参阅代码中的注释:

// Name argument n instead of x, as that latter is commonly used for decimal numbers 
function reverse(n) {
    // Array#reverse method takes no argument.
    // You can use `Math.abs()` instead of changing the sign if negative.
    // Conversion of string to number can be done with unary plus operator.
    var reverseN = +String(Math.abs(n)).split('').reverse().join('');
    // Use a number constant instead of calculating the power
    if (reverseN > 0x7FFFFFFF) {
        return 0;
    }
    // As we did not change the sign, you can do without the boolean isNegative.
    // Don't multiply with -1, just use the unary minus operator.
    // The ternary operator might interest you as well (you could even use it
    //    to combine the above return into one return statement)
    return n < 0 ? -reverseN : reverseN;
}

console.log(reverse(-123));
console.log(reverse(1563847412));

More efficient

更高效

Conversion to string, splitting and joining are relatively expensive operations in comparison with simple arithmetic operations. And so it will be more time (and memory) efficient to solve the problem like this:

与简单的算术运算相比,转换为字符串、拆分和连接是相对昂贵的操作。因此,解决这样的问题会更有时间(和内存)效率:

function reverse(n) {
    var reverseN = 0;
    var sign = n < 0;
    n = Math.abs(n);
    while (n) {
        reverseN = reverseN*10 + (n % 10);
        n = Math.floor(n/10);
    }
    return reverseN > 0x7FFFFFFF ? 0 : sign ? -reverseN : reverseN;
}

console.log(reverse(-123));
console.log(reverse(1563847412));

回答by Robbie Milejczak

However, I am stumped with some of the failing tests:

但是,我对一些失败的测试感到困惑:

Input:
1563847412
Output:
2147483651
Expected: 0

the max 32-bit integer I believe is (2^31)which is 2,147,483,647. This is so that negative values can be stored as well (-2^31)being the 32 bit limit (this is what "signed" means). So any number higher than that, you can return 0 for the sake of your program. If the prompt asked you for "unsigned", the range would be 0to 2^32as you initially assumed.

我认为最大的 32 位整数(2^31)是 2,147,483,647。这是为了可以存储负值以及(-2^31)32 位限制(这就是“有符号”的意思)。所以任何高于这个数字的数字,你都可以为了你的程序返回 0。如果提示要求你为“未签名”,范围将是02^32你最初设想。

In terms of your failed test, 2147483651is 4 greater than 2,147,483,647so you should return 0. Instead you should say reverseX > Math.pow(2,31) - 1

就您失败的测试而言,2147483651大于 4,2,147,483,647因此您应该返回 0。相反,您应该说reverseX > Math.pow(2,31) - 1

What is its significance in JS and what happen if I started going over? (2^32 + 1)

它在 JS 中的重要性是什么?如果我开始复习会发生什么?(2^32 + 1)

Technicially in JS you aren't restricted by this number, JS uses significanddouble-precision floating pointnumbers. So the max value is actually (2^53) - 1

从技术上讲,在 JS 中您不受此数字的限制,JS 使用有效和双精度浮点数。所以最大值实际上是(2^53) - 1

回答by Arul Benito

var reverse = function(x) {
  let ans = parseInt(x.toString().split('').reverse().join('').toString());

  if (x < 0) { ans *= -1; }

  if (ans < (Math.pow(2, 31) * -1) || ans > Math.pow(2, 31) - 1) return 0;
  return ans;
};

console.log("Reverse of 123: " + reverse(123));
console.log("Reverse of -123: " + reverse(-123));

回答by ethanneff

Here is my solution to that question. I wouldn't recommend the split().join() method as it greatly increases time and space complexity.

这是我对这个问题的解决方案。我不推荐 split().join() 方法,因为它会大大增加时间和空间的复杂性。

// 0(n)
var reverse = function(x) {
  var reverse = 0
  var isNegative = x < 0 ? -1 : 1
  x = x * isNegative

  // capture single digits
  if (x / 10 < 1) {
    return x
  }

  // reverse
  while (x >= 1) {
    var diff = parseInt(x % 10)
    reverse = (reverse * 10) + diff
    x = x / 10
  }

  // capture greater than 32bit
  if (reverse > Math.pow(2,31)-1) {
    return 0;
  }

  // capture negative
  return reverse * isNegative
};

回答by venkat7668

This works well

这很好用

var reverse = function(x) {
        let num = Math.abs(x);
        let result = 0;
        let rem;
        while(num>0){
            rem = num % 10;
            result = result * 10 + rem;
            num = Math.floor(num/10);
        }
        if(0x7FFFFFFF < result) return 0
        if(x < 0) return result * -1;
        return result;
    };

回答by Daryl

const reverse = x => {
    let possible = x.toString().split('').reverse();
    let temp, sign, overflow;
    if(Number.isNaN(parseInt(possible[possible.length -1]))) {
      sign = possible.pop();
    }   
    temp = parseInt(possible.join(''));
    overflow = temp > 2**31-1;
    if(sign) {
        if(!overflow) {
            return temp*-1;
        }
    } else {
        if(!overflow){
           return temp;   
        }    
    }
    return 0;
};

回答by Ohm

var reverse = function(x) { let isNegative = x < 0 ? -1 : 1
x = x * isNegative const split =
${x}.split(``) if(split && split.length){ let reversedInteger = `` for(let i=1;i<= split.length;i++) { reversedInteger = reversedInteger + split[(split.length)-i] } if (reversedInteger > Math.pow(2,31)-1) { return 0; } return parseInt(reversedInteger*isNegative) } };

var reverse = function(x) { let isNegative = x < 0 ? -1 : 1
x = x * isNegative const split =
${x}.split(``) if(split && split.length){ let reversedInteger = `` for(let i=1;i<= split.length;i++) { reversedInteger = reversedInteger + split[(split.length)-i] } if (reversedInteger > Math.pow(2,31)-1) { return 0; } return parseInt(reversedInteger*isNegative) } };

Runtime: 72 ms, faster than 82.67% of JavaScript online submissions for Reverse Integer. Memory Usage: 36 MB, less than 28.12% of JavaScript online submissions for Reverse Integer.

运行时间:72 毫秒,比反向整数的 JavaScript 在线提交快 82.67%。内存使用:36 MB,不到反向整数的 JavaScript 在线提交的 28.12%。