Что такое 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;
};