Der beste Weg, um Binärarithmetik in C zu tun?

8

Ich lerne C und schreibe ein einfaches Programm, das zwei Zeichenkettenwerte nimmt, von denen angenommen wird, dass sie Binärzahlen sind, und eine arithmetische Operation entsprechend der Benutzerauswahl ausführen:

  • Fügen Sie die zwei Werte hinzu,
  • Subtrahiere Eingang 2 von Eingang 1 oder
  • Multiplizieren Sie die beiden Werte.

Meine Implementierung geht davon aus, dass jedes Zeichen in der Zeichenfolge ein binäres Bit ist, z. char bin5 = "0101"; , aber es scheint zu naiv zu sein, einen String nach dem anderen zu analysieren. Im Idealfall möchte ich direkt mit den binären Werten arbeiten.

Was ist der effizienteste Weg, dies in C zu tun? Gibt es eine bessere Möglichkeit, die Eingabe als Binärwerte und nicht als scanf() zu behandeln und jedes Bit aus der Zeichenfolge zu erhalten?

Ich habe etwas recherchiert, aber ich fand keinen Ansatz, der aus der Perspektive eines Anfängers offensichtlich besser war. Irgendwelche Vorschläge würden geschätzt werden!

    
jmlane 23.03.2009, 05:09
quelle

5 Antworten

12

Hinweis:
Es gibt nicht viel, das ist natürlich besser, als durch die Zeichenfolge eines Charakters nach dem anderen zu marschieren und sicherzustellen, dass der Benutzer nur Einsen und Nullen eingibt. Denken Sie daran, dass obwohl Sie eine wirklich schnelle Assembly-Routine schreiben könnten, wenn Sie annehmen, alles ist 1 oder 0 , wollen Sie das nicht wirklich tun . Der Benutzer könnte alles eingeben, und Sie würden gerne in der Lage sein, ihnen zu sagen, ob sie vermasselt oder nicht.

Es ist wahr, dass dies im Vergleich zu den paar Zyklen, die es wahrscheinlich braucht, um die tatsächlichen Zahlen hinzuzufügen, unglaublich langsam ist, aber ist es wirklich wichtig, ob Sie Ihre Antwort in einer Nanosekunde oder einer Millisekunde erhalten? Menschen können ohnehin nur 30 Millisekunden Latenz erkennen.

Schließlich dauert es schon viel länger, um vom Benutzer Eingaben zu erhalten und die Ausgabe auf den Bildschirm zu schreiben, als die Zeichenfolge zu parsen oder die Zahlen hinzuzufügen, so dass Ihr Algorithmus hier kaum der Flaschenhals ist. Speichern Sie Ihre fantastischen Optimierungen für Dinge, die rechenintensiv sind: -).

Worauf Sie sich konzentrieren sollten, ist, die Aufgabe weniger arbeitsintensiv zu machen. Und es stellt sich heraus, dass jemand das schon für dich getan hat.

Lösung:
Werfen Sie einen Blick auf die die Hilfeseite strtol() :

%Vor%

Damit können Sie eine Zeichenfolge (nptr) in einer beliebigen Basis in eine lange konvertieren. Es prüft auch Fehler. Beispielverwendung zum Konvertieren einer Binärzeichenfolge:

%Vor%

Bei der Bereitstellung von Base 2 wird strtol zum Konvertieren von Binärliteralen angegeben.

    
tgamblin 23.03.2009, 05:26
quelle
3

Zunächst einmal empfehle ich, dass Sie Dinge wie Strtol verwenden, wie von tgamblin empfohlen, Es ist besser, Dinge zu verwenden, die dir die lib gibt, anstatt das Rad immer wieder neu zu erstellen.

Aber da du C lernst, habe ich eine kleine Version ohne strtol gemacht, es ist weder schnell noch sicher, aber ich habe ein wenig mit der Bit-Manipulation als Beispiel gespielt.

%Vor%     
Johan 23.03.2009 06:26
quelle
1

Um die beste Leistung zu erhalten, müssen Sie zwischen vertrauenswürdigen und nicht vertrauenswürdigen Eingaben für Ihre Funktionen unterscheiden.

Zum Beispiel sollte eine Funktion wie getBinNum() , die Eingaben vom Benutzer akzeptiert, auf gültige Zeichen überprüft und komprimiert werden, um führende Nullen zu entfernen. Zuerst zeigen wir eine allgemeine In-Place-Komprimierungsfunktion:

%Vor%

Geben Sie dann eine Überprüfungsfunktion an, die entweder den übergebenen Wert zurückgibt, oder NULL, wenn sie ungültig war:

%Vor%

Dann funktioniert die Eingabe selbst:

%Vor%

Weitere Funktionen zum Hinzufügen oder Multiplizieren sollten so geschrieben werden, dass davon ausgegangen wird, dass die Eingabe bereits gültig ist, da sie von einer der Funktionen in dieser Bibliothek erstellt wurde. Ich werde den Code für sie nicht bereitstellen, da es für die Frage nicht relevant ist:

%Vor%

Wenn der Benutzer entscheidet, seine Daten von einem anderen Ort als getBinNum() zu beziehen, können Sie ihnen erlauben, checkBinNum() aufzurufen, um sie zu validieren.

Wenn Sie wirklich paranoid wären, könnten Sie jede in Ihren Routinen eingegebene Zahl überprüfen und entsprechend handeln (NULL zurückgeben), aber das würde relativ teure Überprüfungen erfordern, die nicht notwendig sind.

    
paxdiablo 23.03.2009 07:12
quelle
0

Wäre es nicht einfacher, die Strings in Ganzzahlen zu zerlegen und dann die Ganzzahlen mit den ganzen Zahlen zu berechnen?

Ich gehe davon aus, dass es sich um eine Schulaufgabe handelt, aber ich rufe Sie auf, weil Sie es anscheinend sehr gut machen.

    
Chris 23.03.2009 05:25
quelle
-1

Wenn man annimmt, dass eine Zeichenkette eine Binärzahl ist, weil sie nur aus Ziffern der Menge {0,1} besteht, ist das gefährlich. Zum Beispiel, wenn Ihre Eingabe "11" ist, könnte der Benutzer elf in Dezimal, nicht drei in Binär bedeuten. Es ist diese Art von Sorglosigkeit, die zu schrecklichen Fehlern führt. Ihre Eingabe ist zweideutig unvollständig und Sie sollten wirklich verlangen, dass der Benutzer auch die Basis angibt.

    
Liberius 27.11.2010 20:27
quelle