Entwickler-Ecke

C# - Die Sprache - Problem mit C# / .NET Berechnung


AdrianK - Fr 13.03.09 15:06
Titel: Problem mit C# / .NET Berechnung
Hallo,
ich programmiere gerade einen Funktionszeichner mit C#. Um die Funktionen so gut wie
möglich darzustellen erstelle ich die Wertetabelle nicht nur in einer Schritten sondern
in 0.1 Schritten. Das mache ich mit einer simplen for Schleife:

C#-Quelltext
1:
2:
3:
4:
for (Single i = start; i <= end; i = i + (Single) 0.1 )
{
    // Berechnung
}

Jedoch macht C# einen Fehler beim Hochzählen:

Quelltext
1:
2:
3:
-10.0+0.1 = -9.9 
-9.9+0.1  = -9.8
-9.8+0.1  = -9.700000000000011 ?!

ab da stimmt dann natürlich nichts mehr. (Der Fehler tritt auch im Direkt Fenster des Debuggers auf)
Was mache ich falsch? (Ich kann mir eigentlich nicht vorstellen, dass es an C# liegt...
wäre ja ein riesen Bug)
Danke schonmal

@Edit: Tippfehler korigiert


JüTho - Fr 13.03.09 16:42

Das ist ein "Bug" von Intel. Siehe Double und Float: Fehler beim Vergleich und Rundungsfehler [http://www.mycsharp.de/wbb2/thread.php?threadid=64462] (gilt bei Single-Datentyp natürlich genauso) mit Vorschlägen zum Vorgehen.

Übrigens gibt es bei C# folgende Kurzschreibweise:

C#-Quelltext
1:
for (Single i = start; i <= end; i += (Single) 0.1 )                    

Gruß Jürgen


Kha - Fr 13.03.09 16:55

Wenn ich mir die Zahlen so ansehe, geht es glaub ich nicht um einen Rundungsfehler - 0,7 Abweichung wäre doch etwas extrem :zwinker: .

@AdrianK: Falls die ~-9,0 statt -9,7 wirklich stimmen, müsstest du daraus unbedingt mal ein Minimalbeispiel bauen :shock: :gruebel: . Damit kann ich es jedenfalls nicht reproduzieren:

C#-Quelltext
1:
2:
3:
4:
5:
    static void Main(string[] args)
    {
      for (float f = -10; f <= 0; f += 0.1f)
        Console.WriteLine(f);
    }


Quelltext
1:
2:
3:
4:
5:
6:
7:
-10
-9,9
-9,799999
-9,699999
-9,599998
-9,499998
...


bakachan - Fr 13.03.09 17:10

user profile iconKha hat folgendes geschrieben Zum zitierten Posting springen:
Wenn ich mir die Zahlen so ansehe, geht es glaub ich nicht um einen Rundungsfehler - 0,7 Abweichung wäre doch etwas extrem :zwinker: .


Ich vermute mal er hat sich da oben nur verschrieben.

Ansonsten die kleinen Abweichungen beim Schleifenzähler (wie bei Kha's Post) sind normal. Notfalls halt Math.Round auf eine Dezimalstelle.

Falls das oben aber kein Verschreiber ist und da wirklich
Zitat:
-9.8+0.1 = -9.000000000000011 ?!
kam, bin ich ratlos.


AdrianK - Fr 13.03.09 18:47

ja, war ein Verschreiber :) richtig heist es -9.700000000000011
Werds mal mit Decimal / runden versuchen.


Kha - Fr 13.03.09 19:21

user profile iconAdrianK hat folgendes geschrieben Zum zitierten Posting springen:
ja, war ein Verschreiber :)
...

Dann kann ich aber das nicht so stehen lassen ;) :
user profile iconJüTho hat folgendes geschrieben Zum zitierten Posting springen:
Das ist ein "Bug" von Intel.
Auch wenn es in Anführungszeichen steht: Es ist einfach "As Designed".

user profile iconAdrianK hat folgendes geschrieben Zum zitierten Posting springen:
Werds mal mit Decimal / runden versuchen.
Bisher sagtest du nur etwas von Zeichnen und nicht von Ausgeben, dabei sollte doch nicht stören, wenn die Dezimaldarstellung etwas murks ist?


JüTho - Sa 14.03.09 13:02

user profile iconKha hat folgendes geschrieben Zum zitierten Posting springen:
Dann kann ich aber das nicht so stehen lassen ;) :
user profile iconJüTho hat folgendes geschrieben Zum zitierten Posting springen:
Das ist ein "Bug" von Intel.
Auch wenn es in Anführungszeichen steht: Es ist einfach "As Designed".

Ich wollte Intel nicht zu nahe treten. Es ist mir klar, dass es schwierig ist, beliebige Dezimalzahlen (rationale und irrationale) in Bits umzurechnen; natürlich mussten sich die Chip-Designer entscheiden, welche Folgen zu ertragen seien. (Zum Glück bin ich nur Anwendungsprogrammierer.) Ich habe das Wort "Bug" nur übernommen, weil es der Threadstarter gewählt hatte und mir kein besserer kurzer Begriff eingefallen ist. Jürgen