Ich würde gerne ganze Zahlen, positiv oder negativ, in binärer Form sehen.
Eher wie この質問 sondern für JavaScript.
Ich würde gerne ganze Zahlen, positiv oder negativ, in binärer Form sehen.
Eher wie この質問 sondern für JavaScript.
Die negativen Zahlen in vorzeichenlose Darstellung umgewandelt. Jetzt funktioniert die Logik für positive und negative Zahlen. Danke @barlop
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.
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))
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));
Bitte lesen Sie Vincents Antwort und den Kommentar dazu, er würde auch auf Ihren Beitrag zutreffen
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."
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
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.
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("---");
@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.
Nun, wenn -128 alle Nullen in Ihren Darstellungen sind, wie wollen Sie dann die 0 darstellen?
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
}
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.
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 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.
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).
0 Stimmen
Diese Frage ist in höchstem Maße irreführend. "Vielleicht ein bisschen zweideutig" ist zu milde ausgedrückt. Warum taucht das 2er-Komplement weder im Titel noch im Text der Frage auf, wenn es das ist, was Sie eigentlich wollen? Genauso wenig wie ein mehr oder weniger gleichwertiger Ausdruck wie "interne Bit-String-Darstellung". Aus Ihrer Antwort und Ihren Kommentaren zu anderen Antworten schließe ich, dass es Ihnen nicht um das Binärsystem geht, sondern um das 2s-Komplement. Die Fragen, die Sie kritisieren, sehen für mich so aus, als ob sie auf genau Ihre Frage... Es sind nicht die Antworten, die schlecht sind - Ihre Frage ist es.
0 Stimmen
@dingalapadum Nun, bedenken Sie dies. Wie viele verschiedene Möglichkeiten gibt es (in der Praxis), positive und negative ganze Zahlen darzustellen? Es gibt die Vorzeichen-Magnituden-Methode, es gibt das 1er-Komplement und das 2er-Komplement. Und dann gibt es noch "irgendeine benutzerdefinierte Methode". Wenn jemand einen Weg aufzeigt, dann sollte er den Namen der Darstellung angeben. Wenn jemand "-1101" schreibt, ist das nicht binär, oder? Denn ein Minuszeichen ist keine binäre Ziffer. Wenn jemand sagt, dass 1 eine "1" und -1 eine "11111" ist, wie unterscheidet man dann mechanisch zwischen diesen beiden. Wie lautet der Name dieses Systems.
0 Stimmen
Wenn wir über die Darstellung von Zahlen in "x-ary" sprechen, meinen wir, dass wir x Ziffern verwenden, um die Größenordnung der Nummer. Das Vorzeichen der Zahl ist keine Ziffer und wird nicht für den Betrag verwendet. Das Vorzeichen ändert auch nicht den Betrag der Zahl. Ihre Frage bezieht sich auf die Kodierung von Zahlen in einer binären Zeichenfolge. In Ihrem Kommentar sagen Sie bereits, dass Sie sich für das 2er-Komplement interessieren. Warum schreiben Sie es also nicht in den Titel oder in die Frage selbst, um Missverständnisse zu vermeiden, diese Diskussion zu vermeiden und die Frage insgesamt klarer und qualitativ hochwertiger zu gestalten?
0 Stimmen
@dingalapadum Sie spucken nur weitere Ablenkungsmanöver aus, z.B. schreiben Sie mir als eine Art Argument, dass "1011 als Binärzahl verstanden werden kann" (Als ob das eine Neuigkeit sein soll oder ich etwas anderes behauptet hätte).
0 Stimmen
Ich habe "-1011" und nicht "1011" geschrieben. Negative Zahlen scheinen dein ganzes Problem mit den "falschen" Antworten zu sein, richtig? Wie auch immer. IMO ist die Frage in ihrer jetzigen Form von sehr schlechter Qualität und es wäre wirklich einfach, sie zu verbessern. Ich habe nur versucht zu erklären, warum ich so denke. Die "falschen" Antworten und Ihre eigenen Kommentare bestätigen dies. OTOH Sie haben immer noch nicht argumentiert, warum es besser ist, das 2er-Komplement nicht im Titel oder im Hauptteil der Frage zu erwähnen. Nach der Frage zu fragen, "wie man in Binärzahlen umwandelt", aber tatsächlich das 2er-Komplement als Antwort zu verlangen, ist (mit Ihren eigenen Worten) zweideutig . Warum wird die Frage dann nicht einfach präzisiert?
0 Stimmen
Wir wollen diese Diskussion im Chat fortsetzen .
0 Stimmen
Was ist eigentlich eine negative Null in binärer Form in Javascript? Es kann nur im 1er-Komplement sein? Es ist in der Regel als alle binären 1en dargestellt. - > 111111111.... nicht sicher, wie viele. Diese Referenz hat 32bit Zahl binäre Darstellung von -0 als 1 gefolgt von 31 Nullen. - de.wikipedia.org/wiki/Signed_zero
0 Stimmen
@JoePythonKing Was meinen Sie mit "Es kann nur im 1er-Komplement sein?" Du kommst aus Großbritannien, also kannst du vielleicht besser auf Englisch schreiben. Du kannst -1 im 1er-Komplement oder -1 im 2er-Komplement nachschlagen. Computer neigen dazu, das 2er-Komplement gegenüber dem 1er-Komplement zu bevorzugen, aber es ist kein Rätsel, wie man vom einen zum anderen kommt. Es gibt noch einige andere Darstellungen. Wie viele 1en bei negativen Zahlen, z. B. im 2er-Komplement, erforderlich sind, spielt keine Rolle, und wahrscheinlich wäre es auch für das 1er-Komplement egal. Es kommt darauf an, wie viele Bits Sie zum Speichern der Zahl haben!