Что такое 32-разрядное целое число в Javascript?

я делал некоторые проблемы с кодированием и столкнулся с чем-то, с чем я не слишком хорошо знаком. Я более любопытно узнать, что это такое и почему оно там.

подсказка это довольно просто: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.

Я придумал это.

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;
    }
};

тем не менее, я в тупике с некоторыми из неудачных тестов:

Input:
1563847412
Output:
2147483651
Expected: 0

насколько я понимаю, 32-битное целое число равно 2^32. Каково его значение в JS и что произойдет, если я начну сначала? (2^32 + 1)

мой второй вопрос, если я могу задать два, я "ожидал", если значение reverseX превышает 2^32, но он все еще не проходит тест.

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

как мне правильно вернуть 0 когда я превысил 32-разрядное целое число?

4 ответов


верхняя граница подпись целое число, не 232 - 1, но 231 - 1, так как первый бит знака.

Если вы сделаете это сравнение, вы увидите ваш тест дает правильный результат.

имейте в виду, что JavaScript использует IEEE-754 с плавающей запятой представление чисел, Даже если они являются целыми числами. Но точность с плавающей запятой более чем достаточно для выполнения точных расчетов на 32-разрядных целое число. Как вы поняли, вам нужно будет сделать необходимый тест для обнаружения 32-битного переполнения.

некоторые заметки о вашем коде: он передает аргумент в 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));

тем не менее, я в тупике с некоторыми из неудачных тестов:

Input:
1563847412
Output:
2147483651
Expected: 0

максимальное 32-разрядное целое число, которое я считаю (2^31) что составляет 2 147 483 647. Это так, что отрицательные значения могут быть сохранены, а также (-2^31) будучи 32-битным пределом (это то, что означает "подписанный"). Таким образом, любое число выше этого, вы можете вернуть 0 ради своей программы. Если приглашение попросит вас "unsigned", диапазон будет 0 to 2^32 как вы изначально предполагали.

С точки зрения вашего неудачного теста 2147483651 на 4 больше, чем 2,147,483,647 поэтому вы должны вернуть 0. Вместо этого вы должны сказать reverseX > Math.pow(2,31) - 1

каково его значение в JS и что произойдет, если я начну сначала? (2^32 + 1)

Technicially в JS вы не ограничены по этому номеру, И. использует significand двойная точность с плавающей запятой цифры. Так что максимальная стоимость фактически (2^53) - 1


вот мое решение этого вопроса. Я бы не рекомендовал 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
};

Это хорошо

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;
    };