Wie geht Lua mit Ganzzahl- und Gleitkommazahlen um?

11

Soweit ich mich an das Programmieren erinnere, wurde mir beigebracht, Gleitkommazahlen nicht auf Gleichheit zu vergleichen. Beim Lesen der Programmierung in Lua über den Lua- numberTyp stellte ich Folgendes fest:

Der Zahlentyp repräsentiert reelle Zahlen (Gleitkommazahlen mit doppelter Genauigkeit). Lua hat keinen Integer-Typ, da er ihn nicht benötigt. Es gibt ein weit verbreitetes Missverständnis über Gleitkomma-Rechenfehler und einige Leute befürchten, dass selbst ein einfaches Inkrement mit Gleitkommazahlen seltsam werden kann. Tatsache ist, dass bei Verwendung eines Double zur Darstellung einer Ganzzahl überhaupt kein Rundungsfehler auftritt (es sei denn, die Zahl ist größer als 100.000.000.000.000). Insbesondere kann eine Lua-Zahl jede lange ganze Zahl ohne Rundungsprobleme darstellen. Darüber hinaus führen die meisten modernen CPUs Gleitkomma-Arithmetik so schnell wie (oder sogar schneller als) Ganzzahl-Arithmetik aus.

Gilt das für alle Sprachen? Grundsätzlich sind wir in der Ganzzahlarithmetik sicher, wenn wir nicht über das Gleitkomma im Doppel hinausgehen. Oder, um mehr mit dem Fragentitel übereinzustimmen, gibt es etwas Besonderes, das Lua mit seinem numberTyp macht, damit es sowohl als Ganzzahl- als auch als Gleitkommatyp gut funktioniert?

Petr Abdulin
quelle
Siehe auch stackoverflow.com/questions/1848700/…
Joonas Pulakka
@JoonasPulakka danke, das ist eine sehr wertvolle Ergänzung.
Petr Abdulin

Antworten:

10

Lua behauptet, dass Gleitkommazahlen ganzzahlige Zahlen genauso genau darstellen können wie ganzzahlige Typen, und ich bin geneigt, dem zuzustimmen. Es gibt keine ungenaue Darstellung eines gebrochenen numerischen Teils, mit dem man sich befassen muss. Unabhängig davon, ob Sie eine Ganzzahl in einem Ganzzahltyp oder in der Mantisse einer Gleitkommazahl speichern, ist das Ergebnis dasselbe: Diese Ganzzahl kann genau dargestellt werden, solange Sie die Anzahl der Bits in der Mantisse nicht überschreiten , + 1 Bit im Exponenten.

Wenn Sie versuchen, eine tatsächliche Gleitkommazahl (z. B. 12.345) in einer Gleitkommadarstellung zu speichern, sind natürlich alle Wetten deaktiviert. Ihr Programm muss also klar sein, dass die Zahl wirklich eine echte Ganzzahl ist, die die Zahl nicht überschreitet Mantisse, um sie wie eine tatsächliche ganze Zahl zu behandeln (dh in Bezug auf den Vergleich der Gleichheit).

Wenn Sie mehr Ganzzahlgenauigkeit benötigen, können Sie immer eine Bibliothek mit beliebiger Genauigkeit verwenden .

Weiterführende Literatur
Was ist der Maximalwert einer Zahl in Lua?

Robert Harvey
quelle
Was ist mit ihrem zweiten Argument, dh dass Gleitkomma in modernen CPUs genauso schnell oder schneller ist als Ganzzahlarithmetik? Klingt für mich zweifelhaft, selbst wenn Gleitkommazahlen für die Ausführung von Ganzzahlarithmetik verwendet werden.
Andres F.
2
@AndresF. Ich sehe nicht, wie es schneller geht, es sei denn, Sie eliminieren eine Besetzung, indem Sie einen einzigen numerischen Typ anstelle von zwei verwenden.
Robert Harvey
Einverstanden. Macht für mich keinen Sinn. Ich frage mich, ob es aus dem Zusammenhang
Andres F.
1
Ausreichend große Ganzzahlen können nicht genau in einem Gleitkommaobjekt gespeichert werden. Ein 64-Bit doublehat ungefähr 51 Mantissenbits; ungerade ganze Zahlen größer als ungefähr 2 ** 51 haben Rundungsfehler. Eine 64-Bit-Ganzzahl kann größere Ganzzahlwerte genau speichern, da sie keinem Exponenten Bits zuweist.
Keith Thompson
@KeithThompson: Ich dachte, dass dies in meiner Antwort impliziert war, als ich sagte "in der Mantisse gespeichert". Ich werde jedoch die Antwort bearbeiten, um dies zu klären.
Robert Harvey
5

Doppel werden als Mantisse und Exponent gespeichert. Weitere Informationen finden Sie im Format . Grundsätzlich haben alle Zahlen die Form: Mantisse * 2 Exponent . Für jede ganze Zahl kleiner als 2 52 ist der Exponent Null, wodurch die Mantisse Bit für Bit einer vorzeichenlosen 52-Bit-Ganzzahl entspricht. Ein separates Vorzeichenbit wird verwendet, um negative Zahlen anzuzeigen.

In der Tat, auch einige ganzen Zahlen größer als 2 52 genau dargestellt werden, solange alle Ziffern hinter den 52 nd sind Nullen. Außerdem können einige Brüche wie 0,5 genau dargestellt werden. Nur wenn sich der Bruch in Basis 2 kontinuierlich wiederholt (wie 1/3) oder auf andere Weise zu viele Bits hinter dem Radixpunkt benötigt werden, verlieren Sie an Präzision.

Karl Bielefeldt
quelle
Es liegt nicht daran, dass sich Dezimalstellen ständig wiederholen. Dies liegt daran, dass viele Dezimalzahlen (Basis zehn) nicht genau als Zweierpotenz dargestellt werden können.
Robert Harvey
2
In Basis 2 Zahlen , die nicht genau dargestellt werden können , würden seine ständig zu wiederholen. Beispielsweise wird 0,1 Dezimalzahl in Binärform zu 0,0 (0011), wobei sich 0011 kontinuierlich wiederholt.
Karl Bielefeldt
2
Ja genau. Aber nicht in Basis 10 wiederholen. Wiederholung in Basis 2.
Robert Harvey