Warum ist die häufigste Ganzzahl 32 Bit, aber die häufigste Gleitkommazahl 64 Bit?

Aus einem Java- und C # -Hintergrund habe ich gelernt, int (32 Bit) immer dann zu verwenden, wenn ich benötigen eine ganze Zahl und double (64 Bit) beim Umgang mit Bruchwerten. Die meisten Methoden aus ihren jeweiligen Frameworks (JVM und .NET) erwarten normalerweise diese beiden Typen.

Meine Frage ist, warum wir aus Gründen der Konsistenz nicht sowohl long als auch double verwenden. Ich weiß, dass 64 Bit Genauigkeit in ganzen Zahlen die meiste Zeit nicht benötigt werden, aber andererseits benötigen wir normalerweise keine 64 Bit Genauigkeit in Gleitkommazahlen, oder?

Was ist die Gründe dafür, falls vorhanden?

Kommentare

  • “ Es könnte so aussehen, als würde ein Float ist genug für das, was jeder vernünftigerweise brauchen würde, aber es ist ‚ nicht … Tatsächlich sind 64-Bit-Doppel mit ihren 15 Dezimalstellen nicht ‚ nicht gut genug für viele Anwendungen … “ ( Warum benötigen Sie float / double? )
  • Aus einem C-Hintergrund habe ich ‚ gelernt, BigDecimal für Gleitkommazahlen zu verwenden, seit gerundet und Das Vergleichen von FP-Werten ist so problematisch.
  • @TMN I ‚ Ich bin mir nicht sicher, ob ein Typ, der beim Versuch, 1/3 zu berechnen, ausgelöst wird, die Lösung für alles ist .

A. nswer

Bereich vs. Präzision

Eine Sache ist, dass ich die Idee bestreiten würde, dass die häufigste Gleitkommazahl eine 64-Bit-DPFP-Darstellung (Gleitkommadarstellung mit doppelter Genauigkeit) verwendet.

Zumindest in leistungskritischen Real- Zeitfelder wie Spiele, SPFP (Gleitkomma mit einfacher Genauigkeit) sind immer noch weitaus häufiger anzutreffen, da Annäherung und Geschwindigkeit dort der höchsten Genauigkeit vorzuziehen sind.

Eine Möglichkeit, dies zu betrachten, ist jedoch die 32 -bit int repräsentiert einen Bereich von 2^32 Ganzzahlen (~ 4,3 Milliarden). Die häufigste Verwendung von Ganzzahlen wird wahrscheinlich als Index für Elemente sein, und dies ist ein ziemlich gesunder Bereich von Elementen, der schwer zu überschreiten wäre, ohne den mit der heutigen Hardware * verfügbaren Speicher zu überschreiten.

* Beachten Sie, dass beim Zuweisen / Zugreifen auf einen einzelnen zusammenhängenden 4-Gigabyte-Block auch bei 30 Gigabyte frei Speicherplatz auftreten kann, z. B. aufgrund der Kontiguität Anforderungen dieses Blocks.

Eine 32-Bit-Ganzzahl ist auf Befehlsebene nicht immer effizienter, aber es ist Dies ist im Allgemeinen effizienter, wenn es zu einem Array zusammengefasst wird, z. B. weil es die Hälfte des Speichers benötigt (z. B. mehr Indizes, die in eine einzelne Seite / Cache-Zeile passen).

Beachten Sie auch, dass Lightness Races in Orbit weist darauf hin, dass 32-Bit-Ganzzahlen aus einer breiten Perspektive nicht unbedingt häufiger verwendet werden. Ich habe meine enge Perspektive aus einem Feld, in dem 32-Bit ints oft zu Hunderttausenden bis Millionen als Indizes zu einer anderen Struktur zusammengefasst werden – dort kann die Halbierung der Größe helfen Los.

Jetzt kann 64-Bit-DPFP in einigen Kontexten viel mehr als 64-Bit-Ganzzahlen verwendet werden. Dort fügen die zusätzlichen Bits Genauigkeit anstelle von Bereich hinzu. Viele Anwendungen können Präzision erfordern oder haben zumindest eine viel einfachere Programmierzeit mit zusätzlicher Präzision. Das ist wahrscheinlich der Grund, warum 64-Bit-DPFPs in einigen Bereichen häufiger als 64-Bit-Ganzzahlen sind und warum int möglicherweise immer noch 32-Bit ist In vielen Szenarien sogar auf 64-Bit-Plattformen.

Kommentare

  • Ich ‚ würde die Idee anfechten dass der häufigste integrale Datentyp auch 32 Bit breit ist, zumindest in Programmen, die heute auf Standardhardware geschrieben sind. 64-Bit-Plattformen sind derzeit so weit verbreitet.
  • @I Ke: Ich vermute, dass viel Software nur int und long verwendet, ohne sich wirklich um die Reichweite zu kümmern … Ich glaube, dass solche Software heutzutage in beiden Fällen überwiegend 64-Bit-Ganzzahlen verwendet.
  • Hmm, ich stehe korrigiert da, anscheinend ist int im Allgemeinen immer noch 32-Bit , hauptsächlich, um Fehler in genau dieser Art von Code zu vermeiden. Ok, Sie ‚ haben immer noch size_t und long.
  • @LightnessRacesinOrbit Ah, ich verstehe, ich ‚ bin extrem voreingenommen, da ich oft in Codebasen arbeite, die Ganzzahlen zu einer Datenstruktur zusammenfassen, wobei ich mich um die Gesamtspeichergröße kümmere. Ich habe versucht, meine Antwort so neutral wie möglich zu gestalten.
  • @I ke: Persönlich mache ich alle meine Typen auch explizit in der Größe.Aber du und ich sind zweifellos abnormal. 🙂

Antwort

Nun, int und double sind eine Java-Sache. In Objective-C und Swift würden Sie beispielsweise NSInteger oder Int verwenden, dh 32 Bit auf einem 32-Bit-Computer und 64 Bit auf einem 64-Bit-Computer. Groß genug, um eine beliebige Anzahl von Elementen zu zählen, die sich möglicherweise im Speicher befinden. Was auf jeden Fall nützlich ist, ist, fast überall denselben Typ zu verwenden, es sei denn, Sie benötigen in einer bestimmten Situation etwas anderes.

Java versucht, Code zu haben, der in jeder Implementierung gleich ausgeführt wird. Sie sind daher der Meinung, dass Sie unabhängig von der verwendeten Maschine denselben Typ verwenden sollten und dass der Typ unabhängig von derselben Anzahl von Bits haben sollte Die Maschine. Objective-C und Swift (und auch C, C ++) haben einen anderen Standpunkt.

Ganzzahlen werden meistens zum Zählen von Dingen verwendet, und normalerweise müssen Sie nicht so viele Dinge zählen. Gleitkomma-Arithmetik erfordert Präzision, und 32-Bit-Gleitkommazahlen bieten häufig nicht genügend Präzision. Wenn Sie überall 64-Bit-Double verwenden, haben Sie die Chance, immer genug Präzision zu haben, ohne Spezialist für Gleitkomma-Arithmetik zu sein. float ist nicht „t.

Aber welche Konsistenz würde die Verwendung von long und double ergeben? Ganzzahlen und Gleitkommazahlen sind nicht dasselbe. Sie müssen keine konsistente Bitgröße haben. Ich verwende 2D-Punkte und Rechtecke viel. Aus Konsistenzgründen sollten sie also auch 64 Bit sein? Punkte mit 32 Bit pro Komponente und Rechtecke mit 16? Natürlich nicht. Keine Konsistenz erforderlich.

Kommentare

  • Dies ist eine sehr schöne Antwort, die die JVM-Seite erklärt, die Größe jedes Typs unabhängig von der Plattform gleich zu halten.

Antwort

short, int, single und double haben in Java dieselbe Größe wie in den meisten gängigen C-Compilern für 32-Bit- und 64-Bit-Plattformen und C wie Java Es wird klar davon ausgegangen, dass int der Haupt-Integer-Typ und double der Haupt-Gleitkomma-Typ ist. Ich denke, es ist vernünftig zu sagen, dass Java diese Konvention zu dieser Zeit von gängigen C-Compilern geerbt hat.

Ganzzahlen sind normalerweise verwendet für c Es ist ziemlich selten (wenn auch nicht ungewöhnlich), mehr als 2 Milliarden von etwas zählen oder indizieren zu müssen. In der Tat mussten Sie vor C99 herstellerspezifische Typen verwenden, wenn Sie eine 64-Bit-Ganzzahl wollten.

Gleitkommazahlen werden normalerweise als Annäherung an die reellen Zahlen verwendet. Einfache Genauigkeit ist die meiste Zeit gut genug, aber es ist nicht schwer, Probleme zu finden, bei denen ein inakzeptabler Rundungsfehler auftritt. Ich gehe davon aus, dass die Nachfrage aus dem wissenschaftlichen Rechnen dazu geführt hat, dass die Gleitkommaunterstützung mit doppelter Genauigkeit lange vor 64-Bit allgegenwärtig war Ganzzahlunterstützung war.

Was ich merkwürdig finde, ist, dass C die Verwendung von Double zu fördern scheint, während Fortran die Verwendung von Single Precision zu fördern scheint.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.