Ich verwende oft bc
Dienstprogramme zum Konvertieren von Hexadezimalzahlen in Dezimalzahlen und umgekehrt. Es ist jedoch immer ein bisschen Versuch und Irrtum, wie ibase
und obase
sollte konfiguriert werden. Zum Beispiel möchte ich hier den Hex-Wert C0 in Dezimal umwandeln:
$ echo "ibase=F;obase=A;C0" | bc
180
$ echo "ibase=F;obase=10;C0" | bc
C0
$ echo "ibase=16;obase=A;C0" | bc
192
Was ist die Logik hier? obase
( A
in meinem dritten Beispiel) muss sich in derselben Basis befinden wie der Wert, der konvertiert wird ( C0
in meinen Beispielen), und ibase
( 16
in meinem dritten Beispiel) muss sich in der Basis befinden, in die ich konvertiere.
Antworten:
Was Sie eigentlich sagen wollen, ist:
für hex-to-decimal und:
für Dezimal-zu-Hex.
Sie müssen nicht beide
ibase
undobase
für jede Konvertierung mit Dezimalzahlen angeben, da diese Einstellungen standardmäßig 10 sind.Sie haben für beide Umsetzungen wie Binär-Hex geben müssen. In diesem Fall ist es für mich am einfachsten, die Dinge zu verstehen, wenn Sie
obase
zuerst Folgendes angeben :Wenn Sie
ibase
stattdessen zuerst angeben, ändert sich die Interpretation der folgendenobase
Einstellung, sodass der Befehl lauten muss:Dies liegt daran, dass in dieser Reihenfolge der
obase
Wert als Binärzahl interpretiert wird. Geben Sie also 10000₂ = 16 ein, um die Ausgabe in hexadezimaler Form zu erhalten. Das ist ungeschickt.Lassen Sie uns nun herausfinden, warum sich Ihre drei Beispiele so verhalten, wie sie es tun.
echo "ibase=F;obase=A;C0" | bc
180
Das setzt die Eingabebasis auf 15 und die Ausgabebasis auf 10, da ein einstelliger Wert gemäß POSIX in hexadezimaler Schreibweise interpretiert wird . Dies fragt
bc
Sie, was C0 & sub1; & sub0; in der Basis A & sub1; & sub0; = 10 ist, und es beantwortet 180 & sub1; & sub0; richtig, obwohl dies sicherlich nicht die Frage ist, die Sie stellen wollten.echo "ibase=F;obase=10;C0" | bc
C0
Dies ist eine Nullkonvertierung in Basis 15.
Warum? Erstens, weil die einzelne
F
Ziffer hexadezimal interpretiert wird, wie ich im vorherigen Beispiel ausgeführt habe. Aber jetzt, da Sie es auf Basis 15 gesetzt haben, wird die folgende Ausgabe-Basiseinstellung auf diese Weise interpretiert, und 10 & sub1; & sub0; = 15, so daß Sie eine Nullumwandlung von C0 & sub1; & sub0;Richtig, die Ausgabe ist nicht hexadezimal, wie Sie angenommen haben, sondern in Basis 15!
Sie können sich das selbst beweisen, indem Sie versuchen,
F0
statt zu konvertierenC0
. Da dieF
Basis 15 keine Ziffer enthält, wird siebc
geklemmtE0
undE0
als Ausgabe ausgegeben.echo "ibase=16; obase=A; C0"
192
Dies ist das einzige Ihrer drei Beispiele, das wahrscheinlich einen praktischen Nutzen hat.
Es verändert die Eingangsbasis hex zuerst , so dass Sie nicht mehr benötigen , in dem verstehen spec POSIX zu graben , warum
A
als Hex interpretiert, 10 in diesem Fall. Das einzige Problem dabei ist, dass es redundant ist, die Ausgangsbasis auf A & sub1; & sub0; = 10 zu setzen, da dies der Standardwert ist.quelle
Einstellung
ibase
bedeutet,obase
dass Sie dieselbe Basis einstellen müssen . Wenn Sie Ihre Beispiele erläutern, sehen Sie Folgendes:Sie legen fest
bc
, Eingabezahlen wie in Basis 15 mit "ibase = F" dargestellt zu berücksichtigen. "obase = A" setzt die Ausgangsnummern auf Basis 10, was die Standardeinstellung ist.bc
liest C0 als Zahl zur Basis 15: C = 12. 12 * 15 = 180.In diesem Fall setzen Sie die Eingabe auf Basis 15 und die Ausgabe auf 10 - in Basis 15, sodass die Ausgabebasis 15 ist. Die Eingabe von C0 in Basis 15 ist die Ausgabe von C0 in Basis 15.
Setzen Sie den Eingang auf Basis 16 und den Ausgang auf Basis 10 (A in Basis 16 ist 10 in Basis 10).
C0, das zu Basis 10 konvertiert wird, ist: 12 * 16 = 192
Meine persönliche Regel ist es, zuerst obase zu setzen, damit ich base 10 verwenden kann. Dann setze ibase, ebenfalls base 10.
Beachten Sie, dass
bc
eine ironische Ausnahme hat:ibase=A
undobase=A
immer setzt die Ein- und Ausgabe Basis 10. Aus derbc
Manpage:Dieses Verhalten ist in den folgenden Spezifikationen verankert
bc
: Aus der OpenGroup-bc
Spezifikation von 2004 :Aus diesem Grund hat die
ibase=F
Einstellung Ihre Eingabebasis in Basis 15 geändert, und ich habe empfohlen, die Basis immer mit Basis 10 festzulegen. Vermeiden Sie es, sich selbst zu verwirren.quelle
Alle Zahlen werden von GNU bc als die aktuelle Eingabebasis interpretiert, die für die Anweisung gilt, in der die Zahl erscheint. Wenn Sie eine Ziffer außerhalb der aktuellen Eingabe verwenden, interpretieren Sie sie als die höchste in der Basis verfügbare Ziffer (9 in Dezimalform), wenn Teil einer mehrstelligen Zahl oder als ihre normalen Werte, wenn sie als einstellige Zahl verwendet werden (
A
== 10 in Dezimalzahl).Aus dem GNU bc Handbuch :
Beachten Sie jedoch, dass der POSIX-Standard dieses Verhalten nur für Zuweisungen an
ibase
und definiertobase
und nicht in einem anderen Kontext.Aus der SUS-Spezifikation auf bc :
Der Schlüsselfaktor, den Sie vermissen, ist, dass F nicht sechzehn, sondern fünfzehn ist. Wenn Sie also ibase = F einstellen, setzen Sie die Eingabebasis auf fünfzehn.
Deshalb, um portably die ibase in hexadezimalen von einem unbekannten Zustand versetzt, müssen Sie also zwei Aussagen verwenden:
ibase=A; ibase=16
. Zu Beginn des Programms können Sie sich jedoch darauf verlassen, dass es dezimal ist und einfach verwendet wirdibase=16
.quelle
ibase=A; ibase=16
.Es wird immer empfohlen , Satz
ibase
undobase
eine einstellige Zahl verwenden, statt einer Nummer wie16
, da nachbc
Manpage,Dies bedeutet, dass
A,B,...,F
immer die entsprechenden Werte vorhanden10,11,...,15
sind, unabhängig davon, wie hoch der Wertibase
ist. Sie können auch verwendenF+1
, um die Nummer anzugeben16
. Zum Beispiel solltest du besser schreibenAnstatt zu schreiben
echo "ibase=16; obase=A; C0" | bc
, geben Sie an, dass es sich bei der Eingabebasis um16
und bei der Ausgabebasis um handelt10
. Oder wenn Sie zum Beispiel beide möchtenibase
undobase
16 Jahre alt sein möchten , sollten Sie dies besser verwendenanstatt zu verwenden
ibase=16; obase=10
. Wenn Sie Ihre Zahlen in Basis 14 eingeben und in Basis 16 ausgeben möchten, verwenden Sie ebenfallsObwohl Badeformen die gleichen Ergebnisse erzielen, ist erstere weniger fehleranfällig, während letztere zu mehr Verwirrung und Fehlern führen kann.
Der Unterschied zwischen den beiden Formen wird besonders deutlich, wenn Sie sich in der Ausführungsumgebung von befinden
bc
oder Ihre Berechnungen in eine Datei schreiben und diese Datei dannbc
als Argument übergeben. In solchen Situationen müssen Sie möglicherweise die Werte vonibase
undobase
mehrmals ändern , und die Verwendung des letzteren Formulars kann zu ernsthaften Verwirrungen und Fehlern führen. (erlebe es)quelle