Autor Beitrag
AdrianK
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 56

Kubuntu 9.04 Jaunty
Mono 2.4 + MonoDevelop 2.0; Qt Creator
BeitragVerfasst: Fr 13.03.09 15:06 
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:
ausblenden 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:
ausblenden 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


Zuletzt bearbeitet von AdrianK am Fr 13.03.09 18:49, insgesamt 1-mal bearbeitet
JüTho
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2021
Erhaltene Danke: 6

Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
BeitragVerfasst: Fr 13.03.09 16:42 
Das ist ein "Bug" von Intel. Siehe Double und Float: Fehler beim Vergleich und Rundungsfehler (gilt bei Single-Datentyp natürlich genauso) mit Vorschlägen zum Vorgehen.

Übrigens gibt es bei C# folgende Kurzschreibweise:
ausblenden C#-Quelltext
1:
for (Single i = start; i <= end; i += (Single) 0.1 )					

Gruß Jürgen
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: 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:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
    static void Main(string[] args)
    {
      for (float f = -10; f <= 0; f += 0.1f)
        Console.WriteLine(f);
    }

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

_________________
>λ=
bakachan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 503
Erhaltene Danke: 34

W7 (x64) Ultimate
C# / VB.NET (VS2010 Ultimate)
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 56

Kubuntu 9.04 Jaunty
Mono 2.4 + MonoDevelop 2.0; Qt Creator
BeitragVerfasst: Fr 13.03.09 18:47 
ja, war ein Verschreiber :) richtig heist es -9.700000000000011
Werds mal mit Decimal / runden versuchen.
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2021
Erhaltene Danke: 6

Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
BeitragVerfasst: 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