Javascript 将两个32位整数转换为一个有符号64位整数字符串

Javascript 将两个32位整数转换为一个有符号64位整数字符串,javascript,node.js,postgresql,Javascript,Node.js,Postgresql,我需要在PostgreSQL中表示一个64位无符号整数。我将其分解为两个32位无符号整数,high和low。为了允许Postgres接受它,我需要将high和low转换为表示有符号64位整数的字符串 如何将两个32位无符号整数转换为十进制有符号64位整数的字符串?根据,Javascript中的本机数字有53位尾数,因此除非使用专门的库,否则JS无法处理64位整数 无论数据类型和实现限制如何,我假设您希望计算初始64位无符号数的值,将其从[0…2^64-1]范围转换为[-2^63…2^63-1]范

我需要在PostgreSQL中表示一个64位无符号整数。我将其分解为两个32位无符号整数,
high
low
。为了允许Postgres接受它,我需要将
high
low
转换为表示有符号64位整数的字符串

如何将两个32位无符号整数转换为十进制有符号64位整数的字符串?

根据,Javascript中的本机数字有53位尾数,因此除非使用专门的库,否则JS无法处理64位整数

无论数据类型和实现限制如何,我假设您希望计算初始64位无符号数的值,将其从[0…2^64-1]范围转换为[-2^63…2^63-1]范围

high
大概是初始无符号64位数字除以
2^32
,而
low
则是余数

到有符号64位的转换应如下所示:

if high>=2^63 then
   s64 = -(2^64-(high*2^32+low))
 else
   s64 = high*2^32+low;
在PostgreSQL函数中,这可以使用精确的精度
数值类型来完成,以避免中间乘法中的溢出,并将最终结果向下转换为
bigint
(有符号64位):

输入参数必须是
bigint
(64位),因为postgres没有无符号类型。
假设它们在
[0..4294967296]
范围内,并且输出应该在
[-9223372036854775808..9223372036854775807]
范围内。

我根据。错误是我的,聪明是他们的

我还必须添加一系列代码来处理负数(两个补码)

这段代码是ecmascript5,需要稍加修改才能在较旧的浏览器中工作

function convert(hi, lo) {
  function invertBit(bit) {
    return bit == "0" ? "1" : "0";
  }

  function binaryInvert(binaryString) {
    return binaryString.split("").map(invertBit).join("");
  }

  function binaryIncrement(binaryString) {
    var idx = binaryString.lastIndexOf("0");
    return binaryString.substring(0, idx) + "1" + binaryInvert(binaryString.substring(idx + 1));
  }

  function binaryDecrement(binaryString) {
    var idx = binaryString.lastIndexOf("1");
    return binaryString.substring(0, idx) + binaryInvert(binaryString.substring(idx));
  }

  function binaryAbs(binaryString) {
    if (binaryString[0] === "1") {
      return invertBits(binaryDecrement(binaryString));
    }
    return binaryString;
  }

  function to32Bits(val) {
    var binaryString = val.toString(2);
    if (binaryString[0] === "-") {
      binaryString = Array(33 - (binaryString.length - 1)).join("1") + binaryInvert(binaryString.substr(1));
      return binaryIncrement(binaryString);
    }
    return Array(33 - binaryString.length).join("0") + binaryString;
  }

  var fullBinaryNumber = to32Bits(hi) + to32Bits(lo);
  var isNegative = fullBinaryNumber[0] === "1";

  fullBinaryNumber = binaryAbs(fullBinaryNumber);

  var result = "";

  while (fullBinaryNumber.length > 0) {
    var remainingToConvert = "", resultDigit = 0;
    for (var position = 0; position < fullBinaryNumber.length; ++position) {
      var currentValue = Number(fullBinaryNumber[position]) + resultDigit * 2;
      var remainingDigitToConvert = Math.floor(currentValue / 10);
      resultDigit = currentValue % 10;
      if (remainingToConvert.length || remainingDigitToConvert) {
        remainingToConvert += remainingDigitToConvert;
      }
    }
    fullBinaryNumber = remainingToConvert;
    result = resultDigit + result;
  }
  return (isNegative?"-":"") + result;
}
功能转换(高、低){
函数位(位){
返回位==“0”?“1”:“0”;
}
函数binaryInvert(binaryString){
返回binaryString.split(“”).map(invertBit.join(“”);
}
函数二进制增量(二进制字符串){
var idx=binaryString.lastIndexOf(“0”);
返回binaryString.substring(0,idx)+“1”+binaryString(binaryString.substring(idx+1));
}
函数二进制减量(二进制字符串){
var idx=binaryString.lastIndexOf(“1”);
返回binaryString.substring(0,idx)+binaryString(binaryString.substring(idx));
}
函数binaryAbs(binaryString){
if(二进制字符串[0]=“1”){
返回位(二进制减量(二进制字符串));
}
返回二进制字符串;
}
函数到32位(val){
var binaryString=val.toString(2);
如果(二进制字符串[0]=“-”){
binaryString=Array(33-(binaryString.length-1)).join(“1”)+binaryInvert(binaryString.substr(1));
返回二进制增量(binaryString);
}
返回数组(33-binaryString.length);
}
var fullBinaryNumber=至32位(高)+至32位(低);
var isNegative=fullBinaryNumber[0]=“1”;
fullBinaryNumber=binaryAbs(fullBinaryNumber);
var结果=”;
while(fullBinaryNumber.length>0){
var remainingToConvert=“”,resultDigit=0;
对于(变量位置=0;位置
示例:

> // largest negative number -2^63 (just the most significant bit set)
> convert(1 << 31, 0)
'-9223372036854775808'
> // largest positive number
> convert(0x7fffffff, 0xffffffff)
'9223372036854775807'
> // -1 is all bits set.
> convert(0xffffffff, 0xffffffff)
'-1'
//最大负数-2^63(仅为最高有效位集)
>转换(1//最大正数)
>转换(0x7fffffff,0xffffffff)
'9223372036854775807'
>//-1是所有位的集合。
>转换(0xFFFFFF,0xffffffff)
'-1'

high.toString()+low.toString()?@MattBurland没有,因为它不是
1→1
mapping,因为它可能超过64位有符号的最大值。低部分和高部分代表什么?我不明白为什么你不能像@MattBurland那样将这两个部分合并suggested@AndrewWalters高部分是高32位,低部分是低32位。试想一下。
'+(Math.pow(2,32)-1)+(Math.pow(2,32)-1)
=“42949672954294967295”。42949672954294967295大于2^63-1,即有符号整数的最大值。类似于:
> // largest negative number -2^63 (just the most significant bit set)
> convert(1 << 31, 0)
'-9223372036854775808'
> // largest positive number
> convert(0x7fffffff, 0xffffffff)
'9223372036854775807'
> // -1 is all bits set.
> convert(0xffffffff, 0xffffffff)
'-1'