什么是Javascript中的32位整数?

时间:2017-12-01 19:17:41

标签: javascript 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.

我想出了这个。

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

我的第二个问题,如果我可能会问两个问题,那么我是预期的&#34;如果reverseX的值超过2 ^ 32,但它仍未通过测试。

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

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

13 个答案:

答案 0 :(得分:14)

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

如果进行比较,您会发现您的测试结果正确。

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

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

&#13;
&#13;
// 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));
&#13;
&#13;
&#13;

效率更高

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

&#13;
&#13;
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));
&#13;
&#13;
&#13;

答案 1 :(得分:4)

  

但是,我对一些失败的测试感到难过:

Input:
1563847412
Output:
2147483651
Expected: 0

我认为最大的32位整数是(2^31),即2,147,483,647。这样可以存储负值,(-2^31)也是32位限制(这是&#34;签名&#34;的意思)。所以任何数字都高于你,你可以为你的程序返回0。如果提示您要求&#34;未签名&#34;,则您最初假设的范围为02^32

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

  

它在JS中的意义是什么?如果我开始过去会发生什么? (2 ^ 32 + 1)

在JS技术上你不受这个数字的限制,JS使用significand double-precision floating point个数字。所以最大值实际上是(2^53) - 1

答案 2 :(得分:2)

var reverse = function(x) {
  let ans;
  if (parseInt(x) < 0) {
    ans = parseInt(x.toString().split('').reverse().join('').toString()) * -1;
  } else {
    ans = parseInt(x.toString().split('').reverse().join('').toString());
  }
  if (ans < (Math.pow(2, 31) * -1) || ans > Math.pow(2, 31) - 1) return 0;
  return ans;
};

答案 3 :(得分:1)

var reverse = function(x) {
    var reverseX = parseInt(x.toString().split('').reverse().join(''));
    if (reverseX < (Math.pow(2, 31) * -1) || reverseX > Math.pow(2, 31) - 1) return 0;
    return reverseX* Math.sign(x);
    
};
  • 首先将 x 转换成字符串并用 '' 分割它,这样你就会得到数组。

  • 稍后使用数组的 reverse() 函数来反转数组的元素

  • 使用 join('') 函数再次加入之后 现在,检查反转 reverseX 是否导致值超出有符号的 32 位整数范围 [-231, 231 - 1],然后返回 0。

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

答案 4 :(得分:1)

这是我的解决方案

 var reverse = function(x) {


    rev_string = x.toString()
    strArray = rev_string.split("")
    revArray = strArray.reverse()
    new_str =  revArray.join("")

    if (parseInt(new_str) < (Math.pow(2, 31) * -1) || parseInt(new_str) > Math.pow(2,31) - 1) {
         new_str = 0;
    }
    if (Math.sign(x) === -1) {
    
       new_str = parseInt(new_str) * Math.sign(x);
    }


  return new_str;
  };

答案 5 :(得分:0)

以下是我对该问题的解决方案。我不推荐使用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
};

答案 6 :(得分:0)

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

答案 7 :(得分:0)

function reverse(x) {
    let strArr = x.toString().split('');
    let initialString = '';
    for (let i = strArr.length - 1; i >= 0; i--) {
        initialString += strArr[i];
    }
    if (parseInt(initialString) > Math.pow(2, 31) - 1 || parseInt(initialString) < Math.pow(-2, 31)) {
        return 0;
    } else if (x < 0) {
        return -parseInt(initialString);
    } else {
        return parseInt(initialString);
    }
}

答案 8 :(得分:0)

new_df %>% 
  left_join(new_df %>% transmute(Date2, Date3 = lead(Date2)) %>% distinct(), by = c("Date1" = "Date2"))

运行时间:96毫秒,比JavaScript在线提交的73.30%快 反向整数。内存使用量:40.4 MB,小于38.77% 反向整数的JavaScript在线提交。

尽管不是最佳的时空复杂度。

答案 9 :(得分:0)

已经晚了,但还是想给出答案。

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

    if(rev > Math.pow(2, 31)){
     return 0;
    }
     else{        
      return rev*Math.sign(x);
    }    
   }

运行时间:88 毫秒,比反向整数的 95.55% 的 JavaScript 在线提交快。 内存使用:40 MB,不到反向整数的 JavaScript 在线提交的 88.15%。

答案 10 :(得分:0)

我已经尝试过这个解决方案。它有 运行时间:84 毫秒,比 98.31% 的反向整数 JavaScript 在线提交快。在 Leetcode 上。

var reverse = function(x) {
let minus = false;
    x < 0 ? minus=true : minus=false;
    let reverse = parseInt(x.toString().split("").reverse().join(''));
    if (reverse > Math.pow(2,31) - 1) {
        return 0;
    }
    if(minus){
      return parseInt(`-${reverse}`)
    }
    return reverse
};

答案 11 :(得分:0)

这就是我要做的。

var reverse = function(x) {
    let negative = x < 0;
    x = parseInt(String(Math.abs(x)).split("").reverse().join(""));
    return x > 0x7FFFFFFF ? 0 : negative ? -x : x;
};

答案 12 :(得分:-1)

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

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