2013-08-25 13 views
17

In einigen Situationen verwendet man normalerweise einen Integer-Wert, der groß genug ist, um Unendlichkeit darzustellen. Ich verwende normalerweise die größte darstellbare positive/negative Ganzzahl. Dies führt normalerweise zu mehr Code, da Sie vor nahezu allen arithmetischen Operationen prüfen müssen, ob einer der Operanden unendlich ist, um Überläufe zu vermeiden. Manchmal wäre es wünschenswert, gesättigte Integer-Arithmetik zu haben. Aus diesem Grund verwenden einige Leute kleinere Werte für die Unendlichkeit, die ohne Überlauf mehrmals hinzugefügt oder multipliziert werden können. Was interessiert mich ist die Tatsache, dass es sehr häufig ist (besonders bei der Programmierung Wettbewerbe) zu sehen:Warum ist unendlich = 0x3f3f3f3f?

const int INF = 0x3f3f3f3f; 

Warum ist diese Zahl besonders? Es ist Binärdarstellung ist:

00111111001111110011111100111111 

Ich sehe keine besonders interessante Eigenschaft hier. Ich sehe, es ist einfach zu tippen, aber wenn das der Grund wäre, würde fast alles tun (0x3e3e3e3e, 0x2f2f2f2f, etc). Es kann einmal ohne Überlauf hinzugefügt werden, was ermöglicht:

a = min(INF, b + c); 

Aber alle anderen Konstanten würden dann tun. Googeln zeigt mir nur eine Menge Code-Schnipsel, die diese Konstante verwenden, aber keine Erklärungen oder Kommentare.

Kann jemand es finden?

+3

Haben Sie irgendein konkretes Beispiel hierfür in einem allgemeinen Kontext verwendet wird (und nicht innerhalb eines speziellen Algorithmus, wo es Sinn machen könnte)? – Mat

+0

Ich markierte dies als C, da eine schnelle Google-Suche nur C-Code findet, der diese Konstante verwendet. Fühlen Sie sich frei, neu zu schreiben. – JJJ

+1

@Mat: Nehmen Sie zum Beispiel einen beliebigen Algorithmus, der kürzeste Pfade in einem Graphen berechnet. Die Entfernung zu den unerreichbaren Scheitelpunkten vom Anfangsscheitel ist theoretisch unendlich. Du brauchst eine Möglichkeit, das darzustellen (aber Floating Point zu verwenden wäre ein Overkill). Es könnte Beispiele für sehr unterschiedliche Algorithmen geben, die dies verwenden. Ich habe ein konkretes Beispiel gegeben, aber die Technik ist praktisch, wenn Sie "Unendlichkeit" in Pseudocode schreiben. – Gabriel

Antwort

19

ich einige Hinweise darüber here (original content in Chinesisch) gefunden; Die Grundidee ist, dass 0x7fffffff problematisch ist, da es bereits "die Spitze" des Bereichs von 4-Byte-Vorzeichen ist; Wenn Sie also etwas hinzufügen, erhalten Sie negative Zahlen. 0x3f3f3f3f statt:

  • ist immer noch recht groß (gleiche Größenordnung von 0x7fffffff);
  • hat viel Kopffreiheit; wenn Sie sagen, dass der gültige Bereich der ganzen Zahlen beschränkt sich auf Zahlen darunter, können Sie eine beliebige „gültige positive Zahl“, um es hinzuzufügen und immer noch eine unendliche bekommen (das heißt etwas >=INF). Selbst INF+INF überläuft nicht. Dies ermöglicht es, halten immer „unter Kontrolle“:

    a+=b; 
    if(a>INF) 
        a=INF; 
    
  • ist eine Wiederholung des gleichen Bytes, die Sie leicht memset Sachen INF Mittel;

  • auch, wie @ Jörg W Mittag oben bemerkt, hat es eine schöne ASCII-Darstellung, die sowohl auf der Fliege im Speicher suchen zu erkennen ermöglicht Dumps, und es direkt in dem Speicher zu schreiben.
+2

Es ist das größte Byte mit dem 'memset' und' INF + INF' Eigenschaften, weil '2 * 0x40404040' 0x80808080> 0x80000000 ist, was eine mehr als die maximale 32 Bit int ist. –

9

0x3f3f3f3f ist die ASCII-Darstellung der Zeichenfolge ????.

Krugle findet 48 Instanzen dieser Konstante in der gesamten Datenbank. 46 dieser Instanzen befinden sich in einem Java-Projekt, wo sie als Bitmaske für einige Grafikmanipulationen verwendet werden.

1 Projekt ist ein Betriebssystem, in dem es ein unbekanntes ACPI-Gerät darstellt.

1 Projekt ist wieder eine Bitmaske für Java-Grafiken.

Also, in allen Projekten von Krugle indiziert, wird es 47 Mal wegen seiner Bitmuster, einmal wegen seiner ASCII-Interpretation, und nicht ein einziges Mal als eine Darstellung der Unendlichkeit verwendet.

8

ich kann oder nicht eine der frühesten Entdecker von 0x3f3f3f3f sein. Ich habe 2004 einen rumänischen Artikel darüber veröffentlicht (http://www.infoarena.ro/12-ponturi-pentru-programatorii-cc # 9), aber ich benutze diesen Wert seit 2002 zumindest für Programmierwettbewerbe.

Es gibt zwei Gründe dafür:

  • 0x3f3f3f3f + 0x3f3f3f3f nicht int32 läuft. Dafür verwenden einige 100000000 (eine Milliarde).
  • kann man ein Array von ints auf unendlich gesetzt von memset(array, 0x3f, sizeof(array)) tun
Verwandte Themen