Wie manuell (bitweise) ausführen (floaten) x?

8

Nun, hier ist der Funktionskopf der Funktion, die ich implementieren soll:

%Vor%

Wir dürfen keine Float-Operationen oder Castings durchführen.

Nun habe ich versucht, den ersten Algorithmus auf dieser Site zu implementieren: Ссылка

Hier ist mein Code:

%Vor%

Aber es hat nicht funktioniert (siehe Testfehler unten):

%Vor%

Ich weiß nicht, wo ich von hier aus hingehen soll. Wie sollte ich das float von diesem int analysieren?

BEARBEITEN # 1: Möglicherweise können Sie anhand meines Codes sehen, dass ich auch an diesem Algorithmus gearbeitet habe ( siehe hier Website ):

  

Ich habe 10-Bit, Zweierkomplement, ganze Zahlen angenommen, da die Mantisse nur ist   9 Bits, aber der Prozess verallgemeinert zu mehr Bits.

%Vor%

Aber das scheint nicht richtig zu sein. Wie könnte ich 0x80000000 konvertieren? Macht keinen Sinn.

EDIT # 2: Ich denke, es ist, weil ich sage, dass Max Bits 15 ist ... hmmm ...

EDIT # 3: Schrauben Sie diesen alten Algorithmus, ich fange neu an:

%Vor%

Hier ist der Fehler, den ich hier bekommen habe (ich glaube, ich habe den letzten Fehler hinter mir):

%Vor%

Kann hilfreich sein zu wissen, dass: absValOfX = 7f800000 (mit printf)

EDIT # 4: Ah, ich finde den Exponenten falsch, muss von links zählen, dann subtrahiere ich von 32, glaube ich.

EDIT # 5: Ich begann von vorne und versuchte nun mit seltsamen Rundungsproblemen umzugehen ...

%Vor%

-

%Vor%

EDIT # 6

Hat es noch einmal, die Rundung funktioniert nicht richtig. Ich habe versucht ein paar Runden zu hacken, aber es wird einfach nicht funktionieren ...

%Vor%     
slugster 09.09.2012, 03:34
quelle

3 Antworten

3

Das Problem ist, dass das niedrigste int -2147483648 ist, aber das höchste ist 2147483647, also gibt es keinen absoluten Wert von -2147483648. Während du es umgehen könntest, würde ich nur einen speziellen Fall für dieses Ein-Bit-Muster machen (wie du es für 0 tust):

%Vor%

Das andere Problem ist, dass Sie einen Algorithmus kopiert haben, der nur für Zahlen von 0 bis 32767 funktioniert. Weiter unten im Artikel wird erklärt, wie Sie ihn auf alle Ints erweitern, aber er verwendet Operationen, die Sie wahrscheinlich nicht verwenden dürfen .

Ich würde empfehlen, es von Grund auf neu zu schreiben, basierend auf dem Algorithmus, der in Ihrer Bearbeitung erwähnt wurde. Hier ist eine Version in C #, die auf 0 abgerundet wird:

%Vor%     
Gabe 09.09.2012, 03:55
quelle
1

Die Grundformulierung des Algorithmus besteht darin, die Vorzeichen-, Exponenten- und Mantissenbits zu bestimmen und dann das Ergebnis in eine ganze Zahl zu packen. Auf diese Art und Weise zu zerlegen, macht es einfach, die Aufgaben im Code klar zu trennen und das Lösen des Problems (und das Testen Ihres Algorithmus) viel einfacher zu machen.

Das Zeichen-Bit ist am einfachsten, und wenn Sie es loswerden, ist es einfacher, den Exponenten zu finden. Sie können vier Fälle unterscheiden: 0, 0x80000000, [-0x7ffffff, -1] und [1, 0x7fffffff]. Die ersten beiden sind Sonderfälle, und Sie können das Zeichen-Bit in den letzten beiden Fällen (und den absoluten Wert der Eingabe) trivial erhalten. Wenn Sie auf unsigned umwandeln, können Sie mit nicht speziellem Gehäuse 0x80000000 davonkommen, wie ich in einem Kommentar erwähnt habe.

Als nächstes finden Sie den Exponenten - es gibt einen einfachen (und kostspieligen) Looping-Weg und einen kniffligeren, aber schnelleren Weg, dies zu tun. Meine absolute Lieblingsseite dafür ist Sean Andersons Bit Hacks Seite . Einer der Algorithmen zeigt einen sehr schnellen, loop-losen Weg, um das log 2 einer ganzen Zahl in nur sieben Operationen zu finden.

Sobald Sie den Exponenten kennen, ist es einfach, die Mantisse zu finden. Sie löschen einfach das erste führende Bit und verschieben das Ergebnis abhängig vom Wert des Exponenten entweder nach links oder nach rechts.

Wenn Sie den schnellen Protokoll 2 -Algorithmus verwenden, können Sie wahrscheinlich mit einem Algorithmus enden, der nicht mehr als 20 Operationen verwendet.

    
nneonneo 09.09.2012 05:45
quelle
0

Der Umgang mit 0x80000000 ist ziemlich einfach:

%Vor%

Es wird das spezielle Gehäuse -2147483648 entfernt, da dieser Wert als vorzeichenloser Wert dargestellt werden kann und absValOfX immer positiv sein sollte.

    
MSN 09.09.2012 05:07
quelle