2017-07-17 5 views
1

Dies ist zweifellos in anderen (und vielleicht allen) Sprachen der Fall, aber ich habe nur in Python getestet. Meine Frage ist dies: Wenn Arithmetik auf zwei Werte mit unterschiedlicher Genauigkeit ausführt, warum gibt NumPy das Ergebnis in dem Dtype des Werts mit höchster Genauigkeit zurück?NumPy wandelt niedrigere Genauigkeit in Fließkomma-Arithmetik um

Zum Beispiel

import numpy as np 

single = np.array([[1, 2, 3], [4, 5, 6]], np.float32) 
double = np.array([[1, 2, 3], [4, 5, 6]], np.float64) 

diff = single-double 

print "single data type -", single.dtype 
print "double data type -", double.dtype 
print "diff data type -", diff.dtype 

ergibt:

einzigen Datentyp - float32
doppelte Datentyp - FLOAT64
diff Datentyp - FLOAT64

Wie ich schwimmend verstehen Punktpräzision, die zusätzliche zweite Hälfte der Repräsentation diff ist nicht korrekt. Was ist dann der Grund dafür, das Ergebnis auf die höchste Präzision und nicht auf die niedrigste Präzision zu übertragen?

Antwort

2

Der Grund dafür ist ein Prinzip der numerischen Berechnung namens katastrophale Auslöschung.

Betrachten Sie das etwas kleinere Beispiel zwischen zwei Gleitkommazahlen. 3.0000900 - 3.000, wenn es auf 4 Dezimalstellen reduziert wurde, oder in Ihrem Fall auf 4 Bytes reduziert wurde, ist unser resultierender Wert 0. Diese Werte sind jedoch nicht gleich! Das Phänomen, das ich oben demonstriert habe, wird katastrophale Aufhebung genannt. Wir verlieren im Wesentlichen Informationen aufgrund der Kürzung oder sogar Rundung für diese Angelegenheit.

Um dies zu vermeiden, werden die Resultierende dieser Operationen immer in den genaueren Typ umgewandelt, da der Informationsverlust minimal ist.

2

Diese Art Zwang und zumindest in NumPy heißt es wird immer auf den Typ mit höherer Genauigkeit zwingen, weil auf diese Weise Sie Präzision nicht versehentlich verlieren und Sie nicht überläuft bekommen.

Zum Beispiel (in Bezug auf "Überlauf") mit Zwang zu float64 es (Art-of) funktioniert:

>>> np.float64(1e40) - np.float32(1) 
1e40 

Aber wenn es zu float32 zwingen würde würden Sie bekommen:

>>> np.float64(1e40).astype(np.float32) - np.float32(1) 
inf 

Das ist weil der größte float323.4028235e+38 ist.

>>> np.finfo(np.float32) 
finfo(resolution=1e-06, min=-3.4028235e+38, max=3.4028235e+38, dtype=float32) 
0

Die Antwort ist meistens von mathematics and the types of numbers.

Die Typen von types64 enthalten das Ensemble von types32 in gleicher Weise die Arten von reellen Zahlen (floats) die Arten von ganzen Zahlen umfassen.

Wenn Sie Berechnungen durchführen, können Sie ein zufriedenstellendes Ergebnis liefern, wenn Sie die Ergebnismenge in einem größeren Datencontainer (Integer-Typ 64 statt 32) abbilden, aber Sie können nicht garantieren, dass die Ergebnisse beim Mapping nicht abgeschnitten werden eine Menge von Werten in potenziell kürzeren Containern, was zu ungültigen Ergebnissen führt. Das ist schon immer so mit Schwimmer gewesen und zu int

.In den meisten Sprachen führt das Multiplizieren eines Floats mit einem int zu einem float, da ein float (reelle Zahl) mathematisch ein int enthalten kann, während das Gegenteil nicht zutrifft (der Integer-Typ enthält keine reellen Zahlen).

Verwandte Themen