500 Stimmen

Wie konvertiere ich in JavaScript eine Ganzzahl in eine Binärzahl?

Ich würde gerne ganze Zahlen, positiv oder negativ, in binärer Form sehen.

Eher wie この質問 sondern für JavaScript.

3 Stimmen

Die a.toString(2)-Beispiele scheinen bei -1 nicht zu funktionieren

1 Stimmen

Es ist auch möglich, von binär nach dezimal zu konvertieren: stackoverflow.com/questions/11103487/

0 Stimmen

Und wenn ich "binär" sage, ist das vielleicht etwas zweideutig. Ich meine die interne Bitstring-Darstellung, die das 2er-Komplement ist, d.h. positive Zahlen werden zur Basis 2 und mit einer führenden 0 geschrieben (und negative Zahlen werden nicht mit einem Minuszeichen oder mit einer Vorzeichen-Darstellung geschrieben, sondern als Funktion ihres positiven Äquivalents).

2voto

ganesh phirke Punkte 435

Können wir auch das Binärsystem für positive oder negative Zahlen wie folgt berechnen:

function toBinary(n){
    let binary = "";
    if (n < 0) {
      n = n >>> 0;
    }
    while(Math.ceil(n/2) > 0){
        binary = n%2 + binary;
        n = Math.floor(n/2);
    }
    return binary;
}

console.log(toBinary(7));
console.log(toBinary(-7));

0 Stimmen

Befragt wollte auch negativ

0 Stimmen

Die negativen Zahlen in vorzeichenlose Darstellung umgewandelt. Jetzt funktioniert die Logik für positive und negative Zahlen. Danke @barlop

0 Stimmen

Die positiven Zahlen, die mit 1 beginnen, z. B. 7 als 111, sind ein Problem. Denn wenn Sie wollen, dass positive Zahlen bei 1 beginnen, woher wissen Sie dann, was 111 ist, ob es 7 oder -1 ist. Ihr Programm gibt -1 als 11111111111111111111111111111111 und 7 als 111 . Im 2er-Komplement sind 1111111 und 111 die gleiche Zahl. -1.

1voto

Teocci Punkte 5144

Ich würde gerne ganze Zahlen, positiv oder negativ, in binärer Form sehen.

Dies ist eine alte Frage, und ich denke, dass es hier sehr gute Lösungen gibt, aber es gibt keine Erklärung für die Verwendung dieser cleveren Lösungen.

Zunächst müssen wir verstehen, dass eine Zahl positiv oder negativ sein kann. Außerdem bietet JavaScript eine MAX_SAFE_INTEGER Konstante, die einen Wert von 9007199254740991 . Der Grund für diese Zahl ist, dass JavaScript doppeltgenaue Gleitkommazahl Formatnummern gemäß den Angaben in IEEE 754 und kann nur ganze Zahlen zwischen -(2^53 - 1) y 2^53 - 1 .

Jetzt kennen wir also den Bereich, in dem Zahlen "sicher" sind. Außerdem hat JavaScript ES6 die eingebaute Methode Number.isSafeInteger() um zu prüfen, ob eine Zahl eine sichere Ganzzahl ist.

Wenn wir eine Zahl darstellen wollen, ist es logisch, dass n als Binärzahl benötigt diese Zahl eine Länge von 53 Bits, aber zur besseren Darstellung verwenden wir 7 Gruppen von 8 Bits = 56 Bits und füllen die linke Seite mit 0 o 1 auf der Grundlage seines Vorzeichens unter Verwendung der padStart Funktion.

Als Nächstes müssen wir mit positiven und negativen Zahlen umgehen: Positive Zahlen werden addiert 0 s nach links, negative Zahlen addieren 1 s. Auch negative Zahlen benötigen eine Zweierkomplement-Darstellung. Wir können dies leicht beheben, indem wir Folgendes hinzufügen Number.MAX_SAFE_INTEGER + 1 zur Nummer.

Wir wollen zum Beispiel Folgendes darstellen -3 als binär, nehmen wir an, dass Number.MAX_SAFE_INTEGER es 00000000 11111111 (255) では Number.MAX_SAFE_INTEGER + 1 wird 00000001 00000000 (256) . Fügen wir nun die Zahl Number.MAX_SAFE_INTEGER + 1 - 3 dies wird 00000000 11111101 (253) aber wie gesagt, wir werden die linke Seite mit 1 wie diese 11111111 11111101 (-3) stellt dies -3 im Binärformat.

Ein weiterer Algorithmus wird sein, dass wir 1 an die Zahl anhängen und das Vorzeichen wie folgt umkehren -(-3 + 1) = 2 dies wird 00000000 00000010 (2) . Jetzt kehren wir jedes Bit folgendermaßen um 11111111 11111101 (-3) haben wir wieder eine binäre Darstellung von -3 .

Hier haben wir ein funktionierendes Snippet dieser Algos:

function dec2binA(n) {
    if (!Number.isSafeInteger(n)) throw new TypeError('n value must be a safe integer')
    if (n > 2**31) throw 'number too large. number should not be greater than 2**31'
    if (n < -1*(2**31)) throw 'number too far negative, number should not be lesser than 2**31'

    const bin = n < 0 ? Number.MAX_SAFE_INTEGER + 1 + n : n
    const signBit = n < 0 ? '1' : '0'

    return parseInt(bin, 10).toString(2)
        .padStart(56, signBit)
        .replace(/\B(?=(.{8})+(?!.))/g, ' ')
}

function dec2binB(n) {
    if (!Number.isSafeInteger(n)) throw new TypeError('n value must be a safe integer')
    if (n > 2**31) throw 'number too large. number should not be greater than 2**31'
    if (n < -1*(2**31)) throw 'number too far negative, number should not be lesser than 2**31'

    const bin = n < 0 ?  -(1 + n) : n
    const signBit = n < 0 ? '1' : '0'

    return parseInt(bin, 10).toString(2)
        .replace(/[01]/g, d => +!+d)
        .padStart(56, signBit)
        .replace(/\B(?=(.{8})+(?!.))/g, ' ')
}

const a = -805306368
console.log(a)
console.log('dec2binA:', dec2binA(a))
console.log('dec2binB:', dec2binB(a))

const b = -3
console.log(b)
console.log('dec2binA:', dec2binA(b))
console.log('dec2binB:', dec2binB(b))

0voto

Ivan Proskuryakov Punkte 1508

Eine weitere Alternative

const decToBin = dec => {
  let bin = '';
  let f = false;

  while (!f) {
    bin = bin + (dec % 2);    
    dec = Math.trunc(dec / 2);  

    if (dec === 0 ) f = true;
  }

  return bin.split("").reverse().join("");
}

console.log(decToBin(0));
console.log(decToBin(1));
console.log(decToBin(2));
console.log(decToBin(3));
console.log(decToBin(4));
console.log(decToBin(5));
console.log(decToBin(6));

0 Stimmen

Bitte lesen Sie Vincents Antwort und den Kommentar dazu, er würde auch auf Ihren Beitrag zutreffen

0 Stimmen

Dies wurde als Kommentar zu seiner Antwort gepostet, ohne Widerspruch und mit einiger Zustimmung von anderen: "Das mag für ein Informatikstudium nützlich sein, um zu sehen, wie man es manuell macht, um es sich selbst beizubringen, aber das ist nicht das, was ich frage! Wenn man schon das Rad neu erfinden muss, um es manuell zu machen, dann sollte man wenigstens den Vorteil einer höheren Effizienz oder eines größeren Wertevolumens in Kauf nehmen. Ich sehe keine Diskussion von Ihnen, in der ein solcher Vorteil genannt wird."

0 Stimmen

Außerdem versagt Ihre Lösung völlig, denn sie lässt positive Zahlen mit einer 1 beginnen und versagt völlig bei negativen Zahlen, und meine Frage bezog sich auf positiv oder negativ

-1voto

braks Punkte 1365

Ich habe einen anderen Ansatz gewählt, um etwas zu finden, das dies tut. Ich habe beschlossen, diesen Code nicht in meinem Projekt zu verwenden, aber ich dachte, ich würde es irgendwo relevant zu verlassen, für den Fall, dass es für jemanden nützlich ist.

  • Verwendet keine Bitverschiebung oder Zweierkomplement-Zwang.
  • Du wählst die Anzahl der Bits, die herauskommen (es wird nach gültigen Werten von '8', '16', '32' gesucht, aber ich nehme an, du kannst das ändern)
  • Sie können wählen, ob sie als Ganzzahl mit oder ohne Vorzeichen behandelt werden soll.
  • Die Kombination von vorzeichenbehaftet/unvorzeichenbehaftet und die Anzahl der Bits wird auf Bereichsprobleme geprüft, obwohl Sie die Fehlerbehandlung verbessern sollten.
  • Es hat auch die "umgekehrte" Version der Funktion, die die Bits zurück in den int konvertiert. Das werden Sie brauchen, da es wahrscheinlich nichts anderes gibt, das diese Ausgabe interpretieren kann :D

    function intToBitString(input, size, unsigned) { if ([8, 16, 32].indexOf(size) == -1) { throw "invalid params"; } var min = unsigned ? 0 : - (2 size / 2); var limit = unsigned ? 2 size : 2 ** size / 2; if (!Number.isInteger(input) || input < min || input >= limit) { throw "out of range or not an int"; } if (!unsigned) { input += limit; } var binary = input.toString(2).replace(/^-/, ''); return binary.padStart(size, '0'); }

    function bitStringToInt(input, size, unsigned) { if ([8, 16, 32].indexOf(size) == -1) { throw "invalid params"; } input = parseInt(input, 2); if (!unsigned) { input -= 2 ** size / 2; } return input; }

    // EXAMPLES

    var res; console.log("(uint8)10"); res = intToBitString(10, 8, true); console.log("intToBitString(res, 8, true)"); console.log(res); console.log("reverse:", bitStringToInt(res, 8, true)); console.log("---");

    console.log("(uint8)127"); res = intToBitString(127, 8, true); console.log("intToBitString(res, 8, true)"); console.log(res); console.log("reverse:", bitStringToInt(res, 8, true)); console.log("---");

    console.log("(int8)127"); res = intToBitString(127, 8, false); console.log("intToBitString(res, 8, false)"); console.log(res); console.log("reverse:", bitStringToInt(res, 8, false)); console.log("---");

    console.log("(int8)-128"); res = intToBitString(-128, 8, false); console.log("intToBitString(res, 8, true)"); console.log(res); console.log("reverse:", bitStringToInt(res, 8, true)); console.log("---");

    console.log("(uint16)5000"); res = intToBitString(5000, 16, true); console.log("intToBitString(res, 16, true)"); console.log(res); console.log("reverse:", bitStringToInt(res, 16, true)); console.log("---");

    console.log("(uint32)5000"); res = intToBitString(5000, 32, true); console.log("intToBitString(res, 32, true)"); console.log(res); console.log("reverse:", bitStringToInt(res, 32, true)); console.log("---");

0 Stimmen

Schlagen Ihre eigenen Testdaten nicht fehl, ist -128 eindeutig nicht 00000000

0 Stimmen

@barlop der vorzeichenbehaftete Datentyp int8 geht von -128 (00000000) bis 127 (11111111), also ist das so, wie ich es beabsichtigt habe. Meine Bedürfnisse brauchten keine Interoperabilität mit einem anderen Schema.

0 Stimmen

Nun, wenn -128 alle Nullen in Ihren Darstellungen sind, wie wollen Sie dann die 0 darstellen?

-1voto

Diriector_Doc Punkte 520

Dies ist eine Methode, die ich verwende. Es ist eine sehr schnelle und prägnante Methode, die für ganze Zahlen funktioniert.

Wenn Sie möchten, funktioniert diese Methode auch mit BigInts. Sie müssen nur jede 1 a 1n .

// Assuming {num} is a whole number
function toBin(num){
    let str = "";
    do {
        str = `${num & 1}${str}`;
        num >>= 1;
    } while(num);
    return str
}

Erläuterung

Bei dieser Methode werden alle Bits der Zahl durchlaufen, als ob sie bereits eine Binärzahl wäre.

Sie beginnt mit einer leeren Zeichenkette und stellt dann das letzte Bit voran. num & 1 gibt das letzte Bit der Zahl zurück ( 1 o 0 ). num >>= 1 entfernt dann das letzte Bit und macht das vorletzte Bit zum neuen letzten Bit. Der Vorgang wird so lange wiederholt, bis alle Bits gelesen worden sind.

Dies ist natürlich eine extreme Vereinfachung der tatsächlichen Vorgänge. Aber so kann ich es verallgemeinern.

0 Stimmen

In Ihrem ersten Satz steht ".toString(2) ist wahrscheinlich die beste Lösung". -- Versuchen Sie nun, den ersten Kommentar zur Frage zu lesen. Dort steht, dass es nur für positive Zahlen funktioniert. Und versuchen Sie, alle anderen Antworten zu lesen, die dieses Problem mit .toString(2) erwähnen. Ihre Funktion ist interessant, aber Sie sollten angeben, ob sie nur für positive Zahlen oder für positive und negative Zahlen funktioniert.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X