I have a very large number represented as binary in JavaScript:
var largeNumber = '11010011010110100001010011111010010111011111000010010111000111110011111011111000001100000110000011000001100111010100111010101110100010001011010101110011110000011000001100000110000011001001100000110000011000001100000110000111000011100000110000011000001100000110000011000010101100011001110101101001100110100100000110000011000001100000110001001101011110110010001011010001101011010100011001001110001110010100111011011111010000110001110010101010001111010010000101100001000001100001011000011011111000011110001110111110011111111000100011110110101000101100000110000011000001100000110000011010011101010110101101001111101001010010111101011000011101100110010011001001111101'
When I convert it to decimal by use of parseInt(largeNumber, 10)
l it gives me 1.5798770299367407e+199
but when I try to convert it back to binary:
parseInt(`1.5798770299367407e+199`, 2)
it returns 1
(which I think is related to how parseInt
works by rounding value) when I was expecting to see my original binary representation of largeNumber
. Can you explain me such behavior? And how I can convert it back to original state in JavaScript?
EDIT: This question is a result of my experiment where I was playing around with storing and transferring large amount of boolean data. The largeNumber
is a representation of a collection [true,true,false,true ...]
of boolean values which has to be shared between client, client worker and server.
As noted in Andrew L.'s answer, and by several commenters, your largeNumber
exceeds what JavaScript can represent as an integer in an ordinary number without loss of precision—which is 9.007199254740991e+15.
If you want to work with larger integers, you will need a BigInt library or other special-purpose code.
Below is some code demonstrating how to convert arbitrarily large positive integers between different base representations, showing that the exact decimal representation of your largeNumber
is
15 798 770 299 367 407 029 725 345 423 297 491 683 306 908 462 684 165 669 735 033 278 996 876 231 474 309 788 453 071 122 111 686 268 816 862 247 538 905 966 252 886 886 438 931 450 432 740 640 141 331 094 589 505 960 171 298 398 097 197 475 262 433 234 991 526 525
function parseBigInt(bigint, base) {
//convert bigint string to array of digit values
for (var values = [], i = 0; i < bigint.length; i++) {
values[i] = parseInt(bigint.charAt(i), base);
}
return values;
}
function formatBigInt(values, base) {
//convert array of digit values to bigint string
for (var bigint = '', i = 0; i < values.length; i++) {
bigint += values[i].toString(base);
}
return bigint;
}
function convertBase(bigint, inputBase, outputBase) {
//takes a bigint string and converts to different base
var inputValues = parseBigInt(bigint, inputBase),
outputValues = [], //output array, little-endian/lsd order
remainder,
len = inputValues.length,
pos = 0,
i;
while (pos < len) { //while digits left in input array
remainder = 0; //set remainder to 0
for (i = pos; i < len; i++) {
//long integer division of input values divided by output base
//remainder is added to output array
remainder = inputValues[i] + remainder * inputBase;
inputValues[i] = Math.floor(remainder / outputBase);
remainder -= inputValues[i] * outputBase;
if (inputValues[i] == 0 && i == pos) {
pos++;
}
}
outputValues.push(remainder);
}
outputValues.reverse(); //transform to big-endian/msd order
return formatBigInt(outputValues, outputBase);
}
var largeNumber =
'1101001101011010000101001111101001011101' +
'1111000010010111000111110011111011111000' +
'0011000001100000110000011001110101001110' +
'1010111010001000101101010111001111000001' +
'1000001100000110000011001001100000110000' +
'0110000011000001100001110000111000001100' +
'0001100000110000011000001100001010110001' +
'1001110101101001100110100100000110000011' +
'0000011000001100010011010111101100100010' +
'1101000110101101010001100100111000111001' +
'0100111011011111010000110001110010101010' +
'0011110100100001011000010000011000010110' +
'0001101111100001111000111011111001111111' +
'1000100011110110101000101100000110000011' +
'0000011000001100000110100111010101101011' +
'0100111110100101001011110101100001110110' +
'0110010011001001111101';
//convert largeNumber from base 2 to base 10
var largeIntDecimal = convertBase(largeNumber, 2, 10);
function groupDigits(bigint){//3-digit grouping
return bigint.replace(/(\d)(?=(\d{3})+$)/g, "$1 ");
}
//show decimal result in console:
console.log(groupDigits(largeIntDecimal));
//converting back to base 2:
var restoredOriginal = convertBase(largeIntDecimal, 10, 2);
//check that it matches the original:
console.log(restoredOriginal === largeNumber);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With