Floating-point pression Platform abhängies EPSILON
-
@SoIntMan sagte in Floating-point pression Platform abhängies EPSILON:
Guten Morge Dirk, ja das habe ich gerade herausgefunden, dass float (immer) 4byte ist und double(immer) 8 byte, ..
Diese Annahme ist - für C89 - falsch. Das ist sehr sehr häufig der Fall, aber nicht garantiert.
was bedeutet, dass auf einem 32bit System die double Berechnung rechen intensiver sein werden nehme ich an.!?
Rechenintensiver nicht unbedingt, da es auch Fließkommaprozessoren gibt. Es sagt auch nichts über die Anbindung des Speichers aus (wie oft muss für die Daten auf den Speicher zugegriffen werden).
Das war mir nicht bewusst, weil ich wie bei integer davon ausging dass das die breite vom addressbreite abhängt..
Du vermixt da auch Adressen und Daten.
Die Bitbreite sagt ewas über die Daten aus. Dies muss aber nicht mit dem der Adressen übereinstimmen. Die besagt nur, wieviel Speicher maximal adressierbar ist.
-
@SoIntMan sagte in Floating-point pression Platform abhängies EPSILON:
wenn ich nun prüfen will ob Cos(90) == 0 ist , dann braucht ich as Machien eplison!?!? ist das ein gutes beispiel?
Du brauchst ein Epsilon für genau den Anwendungsfall den du gerade hast.
Fließkommazahlen haben (in Dezimaldarstellung) das Format Mantisse x 10^Exponent (^steht für hoch)
Die Anzahl der Stellen von Mantisse und Exponent sind begrenzt und legen die Genauigkeit und den Wertebereich fest.123456 kann man als 1,23456 x 10^6 schreiben. Wenn aber die MAntisse nur 4 Stellen zulässt, dann hast du nur 1,234 x 10^6 was dann 123400 ist oder 123500 (als nächst höhere Zahl).
Da ist das Epsilon mindestens 100.Das gilt umgekehrt für kleiner Zahlen und der Rechner macht das im Binärsystem.
Wenn du damit spielen willst, kannst du mal bei https://www.h-schmidt.net/FloatConverter/IEEE754.html vorbei schauen.
-
@john-0 sagte in Floating-point pression Platform abhängies EPSILON:
Das ist ein schlechtes Beispiel, da dafür das Epsilon nicht gedacht ist. Wenn man rechnet, dann entsteht immer ein Fehler in der Berechnung mit Gleitkommazahlen und dieser pflanzt sich durch die Berechnungen fort. Im Fall von cos(pi/2) könntest Du gerade Glück haben, wenn die cos exakt genug implementiert ist. Man darf aber nicht davon ausgehen, dass cos(pi/2) nur um Epsilon von wahren Wert abweicht.
Sinnvoll wäre es daher cos(pi/2) < akzeptabler_fehler zu prüfen.Ok danke für deine Ausführung. Jetzt habe ich hier ein Konkreter fall. Ich möchte die höhe und breite eine rotierten rechtecks berechnen. geben is das äußere rechteck und der rotations winkel. siehe
hier ergibt sich folgendes:
x = (1/(cos(t)^2-sin(t)^2)) * ( bx * cos(t) - by * sin(t)) y = (1/(cos(t)^2-sin(t)^2)) * (- bx * sin(t) + by * cos(t))
Angenommen t = 45°, bx =100, by =100
da is (cos(t)^2 - sin(t)^2)) == 0 bzw 1/0 =NaN aber ich vermute das wird ne Ausnahme sein.. weil bei != 45 bekomme ich richtige Ergebnisse...
aber das hat dann nicht mit EPLISION zu tun, außer (cos(t)^2 - sin(t)^2)) nähringweise 0 dann kommt bei 1/x ne rießen zahl raus..
Sorry ich denke gerade Laut;)
-
@SoIntMan sagte in Floating-point pression Platform abhängies EPSILON:
Angenommen t = 45°, bx =100, by =100
Die Winkelfunktionen in C verlangen nach Winkel im Bogenmaß (Vollkreis ist ), hast Du so die Werte übergeben?
-
@SoIntMan Du kannst da auf das NaN reagieren.
https://de.wikipedia.org/wiki/NaN
Da das nur bei 45° +/- n*90° auftritt, kannst du dann den Sonderfall behandeln
-
@john-0 jepp habe ich
public double ConvertToRadians(double angle) { return (Math.PI / 180) * angle; }
-
-
@DirkB sagte in Floating-point pression Platform abhängies EPSILON:
@SoIntMan Du kannst da auf das NaN reagieren.
https://de.wikipedia.org/wiki/NaN
Da das nur bei 45° +/- n*90° auftritt, kannst du dann den Sonderfall behandelnvielen dank;) solangsam wirds;)
-
Da hier anscheinend nicht verstanden wird, warum Maschinenepsilon absolut gar nix mit Gleichheit zu tun hat eine Demo (ich spare mir mal eine saubere Templatisierung, die die Bitbreite der Fleißkommazahlen und Integers betrachtet und nehme an
sizeof(double) == sizeof(long)
):#include<iostream> #include<iomanip> #include<cfloat> using namespace std; void print_diff(double lhs, double rhs) { int diff = *(long*)&lhs - *(long*)&rhs; cout << setprecision(20) << lhs<< " ist um " << diff << " Fließkommawerte größer als " << rhs << ". Absolute Differenz ist " << lhs - rhs << '\n'; } int main() { cout << "Maschinenepsilon: " << DBL_EPSILON << '\n'; double literal_one = 1.0; double calculated_one = 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1; print_diff(literal_one, calculated_one); double literal_large_value = 1e50; double calculated_large_value = calculated_one * 1e50; print_diff(literal_large_value, calculated_large_value); double literal_small_value = 1e-50; double calculated_small_value = calculated_one * 1e-50; print_diff(literal_small_value, calculated_small_value); }
Ausgabe auf den meisten Systemen:
Maschinenepsilon: 2.22045e-16 1 ist um 1 Fließkommawerte größer als 0.99999999999999988898. Absolute Differenz ist 1.1102230246251565404e-16 1.0000000000000000763e+50 ist um 1 Fließkommawerte größer als 9.9999999999999986861e+49. Absolute Differenz ist 2.0769187434139310514e+34 1.0000000000000000076e-50 ist um 1 Fließkommawerte größer als 9.9999999999999988892e-51. Absolute Differenz ist 1.1869459682199748434e-66
Wenn jemand erklären möchte, wieso die Zahl 2.22045e-16 irgendetwas damit zu tun haben sollte, dass zwei Werte, die sich um 1.1e-16; 2.1e34; oder 1.2e-66 unterscheiden, trotzdem praktisch gleich sind, dann nur zu! Ich war ja sogar so nett und habe beim ersten Beispiel den Wert 1.0 zum Vergleich genommen, der direkt in der Definition des Epsilon vorkommt, bin aber bloß nach unten abgewichen. Und schon ist die Differenz ein ganz anderer Wert als Epsilon!
-
@SeppJ sagte in Floating-point pression Platform abhängies EPSILON:
Wenn jemand erklären möchte, wieso die Zahl 2.22045e-16 irgendetwas damit zu tun haben sollte, dass zwei Werte, die sich um 1.1e-16; 2.1e34; oder 1.2e-66 unterscheiden, trotzdem praktisch gleich sind, dann nur zu!
Wenn du das Maschinenepsilon mit dem betragsmässig grösseren der beiden Summanden multiplizierst, bekommst du eine gute Abschätzung für den maximal möglichen Fehler.
-
@SeppJ danke dass du dir die Mühe gibt das an einem Beispiel zu erklären;)
-
@SeppJ sagte in Floating-point pression Platform abhängies EPSILON:
Wenn jemand erklären möchte, wieso die Zahl 2.22045e-16 irgendetwas damit zu tun haben sollte, dass zwei Werte, die sich um 1.1e-16; 2.1e34; oder 1.2e-66 unterscheiden, trotzdem praktisch gleich sind, dann nur zu!
Du hast ja auch vergessen den StandardScaler zu nutzen.
Oder alternativ den MinMaxScaler oder RobustScaler. Damit habe ich aber noch keine praktische Erfahrungen gesammelt.
-
Es gibt bereits eine gute Abhandlung der Problematik: What Every Computer Scientist Should
Know About Floating-Point Arithmetic.
-
@john-0 ok overkill, aber ich schau es mir mal an;=)