Tom Wu's excellent big integer library JSBN is missing the longValue function, so I have to write such myself. Below is my code, but it cannot produce right results.
var Cast_Int64 = function (v)
{
var bytes = v.toByteArray();
var value =
(
(new BigInteger(bytes[0]).and(new BigInteger(255))).shiftLeft(new BigInteger(56))
)
.or(
(new BigInteger(bytes[1]).and(new BigInteger(255))).shiftLeft(new BigInteger(48))
)
.or(
(new BigInteger(bytes[2]).and(new BigInteger(255))).shiftLeft(new BigInteger(40))
)
.or(
(new BigInteger(bytes[3]).and(new BigInteger(255))).shiftLeft(new BigInteger(32))
)
.or(
(new BigInteger(bytes[4]).and(new BigInteger(255))).shiftLeft(new BigInteger(24))
)
.or(
(new BigInteger(bytes[5]).and(new BigInteger(255))).shiftLeft(new BigInteger(16))
)
.or(
(new BigInteger(bytes[6]).and(new BigInteger(255))).shiftLeft(new BigInteger(8))
)
.or(new BigInteger(bytes[7]).and(new BigInteger(255)));
return value;
};
I have an array of integer strings, which I try to cast to Int64, but it doesn't provide right answers.
The array of integer strings is:
var arr = [ "90655", "123423", "1", "9223372032559808512", "18446744071562067967", "4294967295", "18446744071562067968", "0", "346457745533644", "18446744073623153357" ];
The right answers (in C# test base using (Int64)) are:
90655 123423 1 9223372032559808512 -2147483649 4294967295 -2147483648 0 346457745533644 -86398259
And my incorrect answers are:
99676226616033280 135705023634997248 72057594037927936 9223372032559808512 72057594029539327 72057594021150720 72057594029539328 0 88693182856612864 72057594037590442
I have jsbin, where you can test the function.
EDIT: If I replace Cast_Int64 with this:
var Cast_Int64 = function (v)
{
return v;
}
then all goes well, but all numbers that should be negative (in C# test base), will be wrong:
90655 123423 1 9223372032559808512 18446744071562067967 4294967295 18446744071562067968 0 346457745533644 18446744073623153357
Code that works (adapted from the accepted answer):
var Cast_Int64 = function (v)
{
if (v.compareTo(new BigInteger(2).pow(new BigInteger(63))) > 0)
v = v.subtract(new BigInteger(2).pow(new BigInteger(64)));
return v;
}
Or shorter (and a bit faster):
var Cast_Int64 = function (v)
{
if (v.compareTo(new BigInteger("9223372036854775808",10)) > 0)
v = v.subtract(new BigInteger("18446744073709551616",10));
return v;
}
I put the replaced code in jsbin. BTW, there are already Cast_UInt64, Cast_Int32 and Cast_UInt32 functions.