Javascript 将两个32位整数转换为一个有符号64位整数字符串
我需要在PostgreSQL中表示一个64位无符号整数。我将其分解为两个32位无符号整数,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]范
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'