2016-09-05 4 views
3

Ich habe in Dezimalzahlen und wieder eine sehr große Zahl dargestellt als binäre in JavaScript:ein große Anzahl von binären in JavaScript

var largeNumber = '11010011010110100001010011111010010111011111000010010111000111110011111011111000001100000110000011000001100111010100111010101110100010001011010101110011110000011000001100000110000011001001100000110000011000001100000110000111000011100000110000011000001100000110000011000010101100011001110101101001100110100100000110000011000001100000110001001101011110110010001011010001101011010100011001001110001110010100111011011111010000110001110010101010001111010010000101100001000001100001011000011011111000011110001110111110011111111000100011110110101000101100000110000011000001100000110000011010011101010110101101001111101001010010111101011000011101100110010011001001111101' 

Wenn ich es zu konvertieren, indem die Verwendung von parseInt(largeNumber, 10) l dezimal es gibt mir 1.5798770299367407e+199 aber wenn ich versuche, es zu binär zu konvertieren zurück:

parseInt(`1.5798770299367407e+199`, 2) 

es gibt 1 (was ich denke, ist damit zusammen, wie parseInt Arbeiten von Rundungswert), wenn ich es erwartet hatte meine ursprüngliche binäre Darstellung vonzu sehen. Kannst du mir solches Verhalten erklären? Und wie kann ich es in JavaScript zurück in den ursprünglichen Zustand konvertieren?

EDIT: Diese Frage ist ein Ergebnis meines Experiments, in dem ich um spiele mit Speicherung und große Menge an boolean Daten übertragen werden. Die largeNumber ist eine Darstellung einer Sammlung [true,true,false,true ...] boolescher Werte, die zwischen Client, Client Worker und Server gemeinsam genutzt werden müssen.

+1

'parseInt' ist keine Methode zur Konvertierung von einem Zahlensystem in ein anderes. Sie müssen lesen, was es _actually_ tut, dann überdenken, wie Sie Ihr Endergebnis erreichen. –

+0

_ "Ich habe eine sehr große Zahl als binär dargestellt" _ Wie wurde die ursprüngliche Zahl in 'largeNumber' konvertiert? – guest271314

+2

Das Konvertieren einer numerischen Zeichenfolge in eine Zahl ist kein verlustfreier Prozess. Zahlen haben nur 64 Bits, sie können nicht viele Informationen speichern. – Oriol

Antwort

2

Wenn Sie es zurück in Binär konvertieren, werden Sie es nicht als Basis 2 analysieren, das ist falsch. Sie versuchen auch, eine Ganzzahl als Gleitkommazahl zu analysieren, dies kann zu Ungenauigkeiten führen. Mit dieser Zeile:

parseInt(`1.5798770299367407e+199`, 2) 

Sie sagen JS, eine Basis 10 als Basis 2 zu analysieren! Was Sie tun müssen, um konvertieren ist es wie so (beachten Sie die Verwendung von parseFloat) binär:

var largeNumber = '11010011010110100001010011111010010111011111000010010111000111110011111011111000001100000110000011000001100111010100111010101110100010001011010101110011110000011000001100000110000011001001100000110000011000001100000110000111000011100000110000011000001100000110000011000010101100011001110101101001100110100100000110000011000001100000110001001101011110110010001011010001101011010100011001001110001110010100111011011111010000110001110010101010001111010010000101100001000001100001011000011011111000011110001110111110011111111000100011110110101000101100000110000011000001100000110000011010011101010110101101001111101001010010111101011000011101100110010011001001111101'; 
 

 
//intLN is integer of large number 
 
var intLN = parseFloat(largeNumber, 2); //here, you used base 10 to parse as integer, Incorrect 
 
console.log(intLN); 
 

 
var largeNumberConvert = intLN.toString(2); //here, we convert back to binary with toString(radix). 
 
console.log(largeNumberConvert);

Vorher umgewandelt Sie eine Dezimalzahl in Binär. Was Sie tun müssen, ist toString(radix) nennt es in binären zurück zu konvertieren, so:

var binaryRepresentation = integerFormOfLargeNumber.toString(2); 

Wenn Sie am Ausgang schauen, sehen Sie:

Infinity 
Infinity 

Da Ihre binäre Zahl ist recht groß, es kann die Ergebnisse beeinflussen. Da JS bis zu 64 Bit unterstützt, ist die Anzahl viel zu groß. Es verursacht Infinity und ist ungenau. Wenn Sie versuchen, erneut Umwandlung-die largeNumberConvert von binären wie dies in Dezimalzahlen:

parseInt(largeNumberConvert, 10); 

Sie können sehen, dass es Infinity ausgibt.

+0

'largeNumber' ist zu groß dafür. – Arnial

+0

Ich weiß, ich bearbeite meine Antwort – Li357

+0

Die andere Feinheit hier ist negative Zahlen: http://stackoverflow.com/questions/9939760/how-do-i-convert-an-integer-to-binary-in-javascript –

5

Wie bereits erwähnt in Andrew L.'s answer, und von mehreren commenters, Ihre largeNumber übersteigt, was JavaScript als eine ganze Zahl in einer gewöhnlichen Zahl ohne Genauigkeitsverlust darstellen kann — die 9.007199254740991e+15 ist.

Wenn Sie mit größeren Ganzzahlen arbeiten möchten, benötigen Sie eine BigInt-Bibliothek oder einen anderen speziellen Code.

Unten finden Sie einige Code demonstriert, wie beliebig große positive ganze Zahlen zwischen verschiedenen Basis Darstellungen zu konvertieren, dass die genaue Dezimaldarstellung Ihrer largeNumber zeigt

15 798 770 299 367 407 029 725 345 423 297 491 683 ist 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);

Verwandte Themen