Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   C# kann nicht rechnen oder bin ich zu blöd?¿? (https://www.delphipraxis.net/114325-c-kann-nicht-rechnen-oder-bin-ich-zu-bloed-%BF.html)

Phoenix 23. Mai 2008 12:25


C# kann nicht rechnen oder bin ich zu blöd?¿?
 
Hi.

Folgender Fall in C#:
Code:
public class Test
{
   private double _Qs = 30; // Einheit: tonnen / stunde
   public double Qs
   {
      get { return _Qs; }
      set { _Qs = value; }
   }

   // simple Umrechnung: t/h --> kg/s
   public double Ms
   {
      get { return Qs / (1000 / 3600); }
      set { Qs = value * (1000 / 3600); }
   }
}
Das sieht mir auf den ersten Blick sehr richtig aus.

Beispiel im (Windows-) Taschenrechner mit 30 t/h in 108 kg/s:
30 / (1000 / 3600) = 108

Dieser getter - Code liefert mir jedoch im Debugger und in der Ausgabe (VS 2008) als Wert 'Infinity' zurück. Was fatal ist, da ich damit ja weiter rechnen muss...

Und jetzt bin ich echt perplex: Wieso kommt da so ein offensichtlich falsches Ergebnis bei raus?

Luckie 23. Mai 2008 12:30

Re: C# kann nicht rechnen oder bin ich zu blöd?¿?
 
Schreib mal:
Code:
private double _Qs = 30.0;
Und bei den Konstanten, mit denen du dividierst, auch.

Phoenix 23. Mai 2008 12:31

Re: C# kann nicht rechnen oder bin ich zu blöd?¿?
 
Joa.. integer 3600 / integer 1000 = integer 0...
Robert hat mich da grad nett drauf aufmerksam gemacht.. Mannomann...

Also Anwtort. Ich bin zu blöd :stupid:

Medium 23. Mai 2008 12:33

Re: C# kann nicht rechnen oder bin ich zu blöd?¿?
 
Alternativ stell deinen Zahlen ein "f" bzw. "d" nach. Also "(1000d / 3600d)".

Die Muhkuh 23. Mai 2008 12:34

Re: C# kann nicht rechnen oder bin ich zu blöd?¿?
 
Zitat:

Zitat von Phoenix
Also Anwtort. Ich bin zu blöd :stupid:

Das gleiche Problem hat mich in Java auch ne Stunde gekostet bis ich drauf gekommen bin. :-?

Elvis 23. Mai 2008 12:41

Re: C# kann nicht rechnen oder bin ich zu blöd?¿?
 
Zitat:

Zitat von Phoenix
Also Anwtort. Ich bin zu blöd :stupid:

Das war es eiegtnlich worauf ich ihn nett hingewiesen habe.
Der Teil mit Integer/Integer=Integer war nur Alibi... :mrgreen:

Phoenix 23. Mai 2008 12:44

Re: C# kann nicht rechnen oder bin ich zu blöd?¿?
 
Nu is gut, ja? :-p

Jürgen Thomas 23. Mai 2008 13:48

Re: C# kann nicht rechnen oder bin ich zu blöd?¿?
 
Wenn das Thema schon "C# kann nicht rechnen" heißt, möchte ich noch darauf hinweisen, dass double ungenau ist und deshalb zu Rechenfehlern führen kann.

Denen, die sich hier geäußert haben, sage ich damit sicher nichts Neues; aber für den Fall, dass andere Leser darüber stolpern, wollte ich darauf hinweisen. Jürgen

Luckie 23. Mai 2008 13:56

Re: C# kann nicht rechnen oder bin ich zu blöd?¿?
 
Was heißt ungenau? Wenn ich nur zwei Nachkommastellen brauche, dann reicht auch Double.

mkinzler 23. Mai 2008 14:05

Re: C# kann nicht rechnen oder bin ich zu blöd?¿?
 
Zitat:

Zitat von Luckie
Was heißt ungenau? Wenn ich nur zwei Nachkommastellen brauche, dann reicht auch Double.

Ween aber viele komplexe Berechnungen durchgeführt werden, addieren sich Rundungsfehler

Medium 23. Mai 2008 14:12

Re: C# kann nicht rechnen oder bin ich zu blöd?¿?
 
Kommt immer darauf an, wie viele Rechnungen man schon angestellt hat, da sich die Ungenauigkeiten nach mehreren vielen Operationen durchaus auch schon im Ganzzahlanteil bemerkbar machen können. Dass ein Mal Zuweisen und dann Anzeigen nicht dazu führt ist klar, aber wenn man viel rechnet kann es eng werden. Ist allerdings im höchsten Maße vom Einzelfall abhängig, und sollte im kleinsten Teil der üblichen Anwendungen überhaupt ins Gewicht fallen. Man muss es nur im Hinterkopf haben.

Edit: Hi Red-Box :)

alzaimar 26. Mai 2008 13:56

Re: C# kann nicht rechnen oder bin ich zu blöd?¿?
 
Immer wieder das Gleiche: Floating point ist nicht ungenau, sondern auf 8-20 Stellen (je nach Datentyp) *genau*. Man kann beruhigt damit rechnen, es gibt eigentlich keinen praktischen Fall, bei dem die Genauigkeit (von Extended) nicht ausreicht. Bis sich die 20.te Stelle zu einer relevanten 7.-8. Stelle hochschaukelt (Das sind ist ein Faktor von 10^12 !!). vergeht so Einiges.

Ich finde es nicht richtig, wenn diese Unwahrheit (Floats sind ungenau) hier immer wieder verbreitet wird. Richtig wird die Aussage damit auch nicht. Ich verwende Floats seit 25 Jahren in numerischen Verfahren (Messdatenerfassung, Auswertung, Iteration, Integration etc.) und hatte noch *nie* Probleme damit. Oh, doch, 1x: Es ging um Nullstellenberechnung (Newton) und da kann eine sehr große durch eine sehr kleine Zahl geteilt werden. Da würde aber auch BCD (der angebliche Heilsbringer) alle Viere von sich strecken.

gammatester 26. Mai 2008 14:50

Re: C# kann nicht rechnen oder bin ich zu blöd?¿?
 
Zitat:

Zitat von alzaimar
Immer wieder das Gleiche: Floating point ist nicht ungenau, sondern auf 8-20 Stellen (je nach Datentyp) *genau*. Man kann beruhigt damit rechnen, es gibt eigentlich keinen praktischen Fall, bei dem die Genauigkeit (von Extended) nicht ausreicht. Bis sich die 20.te Stelle zu einer relevanten 7.-8. Stelle hochschaukelt (Das sind ist ein Faktor von 10^12 !!). vergeht so Einiges.

Ich finde es nicht richtig, wenn diese Unwahrheit (Floats sind ungenau) hier immer wieder verbreitet wird. Richtig wird die Aussage damit auch nicht...

Das Rechnen ist in der Tat meist nicht problematisch, sondern der naive Umgang mit Vergleiche. Wie oft kommt es nicht vor, daß sich Anwender wundern, weshalb folgendes Programm hängt, zB (in Pascal)

Delphi-Quellcode:
var
  x: extended;
begin
  x := 0.0;
  repeat
    x := x+0.1;
    {Mach was mit x}
  until x=1.0;
end;
Und die Ungenauigkeit ist selbstverständlich da (Größenordnung 1e-7, 1e-16 etc). Sinnvollerweise sollten Compiler Warnungen oder Hinweise ausgeben, wenn Fließkommaausdrücke auf Gleichheit getestet werden.

Gammatester

alzaimar 26. Mai 2008 15:01

Re: C# kann nicht rechnen oder bin ich zu blöd?¿?
 
Zitat:

Zitat von gammatester
Sinnvollerweise sollten Compiler Warnungen oder Hinweise ausgeben, wenn Fließkommaausdrücke auf Gleichheit getestet werden.

DAS sollte mal auf die Feature-Liste von CodeGear.

Medium 26. Mai 2008 15:14

Re: C# kann nicht rechnen oder bin ich zu blöd?¿?
 
alzaimar, du wiedersprichst dir hier leider selbst. Ein Typ, der bis zu einer gewissen Stelle genau ist, ist insgesamt gesehen immer noch ungenau. Oder sagen wir besser: Ungenau genug, um damit wenn man es nicht im Hinterkopf hat, ganz kräftig auf die Nase zu fallen. Dass Fälle, in denen sich die Abweichungen relevant äussern selten sind, ist nicht genug, um die gesamte Aussage zu falsifizieren. Das macht den Datentyp aber nicht schlecht oder unbrauchbar - hier will keiner die Float-Apokalypse hervorsagen.

Man kann sicherlich getrost alle Kundenrechnungen der letzten 10 Jahre mit Doubles aufsummieren*, und die 2. Nachkommastelle ist akkurat, aber gerade wenn wir in den Bereich physikalischer Simulationen kommen, oder analytischer Mathematik, wirst du gelegentlich nicht drum herum kommen manchen Algorithmus bewusst darauf hin zu entwickeln, dass sich diese Fehler in Grenzen halten.
* Obwohl, aus gutem Grund, hier idR Integer genommen werden ;)

Nochmal: Die "Otto-Normal-Anwendung" merkt da vermutlich nie was von, besonders wenn nur simple Operationen wie + und - auftauchen, und sich die betrachteten Werte in einem genügend kleinen Intervall um 0 bewegen. Auch komplexere Dinge sind noch locker drin, aber ab und an, abhängig vom Algo und den Daten, wirds halt eng.


Jürgen will hier sicherlich keine "Benutzt nie Floats!"-Kampagne starten, aber so manche Frage (besonders eben die Prüfung auf Gleichheit) würde evtl. nicht hier im Forum landen, wenn man sich dieses Umstandes nur bewusst ist.


Edith findet die Idee mit der Warnung auch spitzenklasse :)

alzaimar 26. Mai 2008 19:05

Re: C# kann nicht rechnen oder bin ich zu blöd?¿?
 
Zitat:

Zitat von Medium
alzaimar, du wiedersprichst dir hier leider selbst.

Niemals! Ich habe immer Recht! Ausgenommen, wenn ich mal nicht Recht habe...

Zitat:

Zitat von Medium
Ein Typ, der bis zu einer gewissen Stelle genau ist, ist insgesamt gesehen immer noch ungenau.

Meinst Du das persönlich ("Der Typ") :mrgreen: ? Im Ernst, ich schrieb "nicht ungenau, sondern auf xxx Stellen genau". Das ist so ähnlich wie 'Glass halb voll oder halb leer'.

Zitat:

Zitat von Medium
gerade wenn wir in den Bereich physikalischer Simulationen kommen, oder analytischer Mathematik, wirst du gelegentlich nicht drum herum kommen manchen Algorithmus bewusst darauf hin zu entwickeln, dass sich diese Fehler in Grenzen halten.

Absolut korrekt, nur ist das keine Eigenheit der floats, sondern der Limitierung auf X signifikante Stellen. Auch bei BCD schaukelt sich der Fehler hoch.
Zitat:

Zitat von Medium
Nochmal: ... aber ab und an, ..., wirds halt eng.

Jupp. "Normalisieren" heißt das Zauberwort.

mkinzler 26. Mai 2008 19:08

Re: C# kann nicht rechnen oder bin ich zu blöd?¿?
 
Zitat:

Niemals! Ich habe immer Recht!
§1: alzaimar hat immer Recht
$2: Sollte ewr mal nichr Recht haben, gilt §1 :zwinker:

Zngenauigkeiten sind OK, wenn man weiss wie groß diese sind.

alzaimar 26. Mai 2008 22:17

Re: C# kann nicht rechnen oder bin ich zu blöd?¿?
 
@mkinzler: So ist es richtig, außer wenn es nicht richtig ist, aber selbst dann ist es nicht falsch.

grenzgaenger 26. Mai 2008 22:25

Re: C# kann nicht rechnen oder bin ich zu blöd?¿?
 
kommt halt immer auf den anwendungsfall an, welchen datentyp man verwendet. im kaufmännischen bereich, gibts nicht viel mehr als + und - und wenn es doch mal mehr wird, dann müssen beide seiten sowieso nicht zusammen passen.


real's sind schon ok. aber nicht für jeden anwendungsfall. genaus, kann man BCD für die meisten probleme vergessen, wo man mit formeln jonglieren muss...

also, beide kampagnen kann man vergessen. man muss nur unterscheiden und bedarfsgerecht den richtigen datentyp auswählen :-)


btw: das mit dem compiler hinweis, wär mal was :-)

Medium 27. Mai 2008 01:32

Re: C# kann nicht rechnen oder bin ich zu blöd?¿?
 
Zitat:

Zitat von alzaimar
Niemals! Ich habe immer Recht! Ausgenommen, wenn ich mal nicht Recht habe...

Man muss nur scharf aufpassen, dass man nicht so weit Recht hat, dass man schon fast wieder Link hat... :gruebel: ...glaub ich =)

Zitat:

Zitat von alzaimar
Absolut korrekt, nur ist das keine Eigenheit der floats, sondern der Limitierung auf X signifikante Stellen. Auch bei BCD schaukelt sich der Fehler hoch.

Aja okay, wenn du bei "Floats" an das Konzept an sich denkst, geb ich dir vollkommen Recht. Ich denk immer gleich an die bestehenden Datentypen - da liegt der Hase nebem dem Hund im Pfeffer begraben.

Zitat:

Zitat von alzaimar
Jupp. "Normalisieren" heißt das Zauberwort.

Was is heutzutage schon noch normal :roll:


Okay, puh. nur 2/3 OT. Muss reichen für heute!


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:15 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz