Laden...

Problem mit einem boolschen Ausdruck

Erstellt von Adlervitriol vor 16 Jahren Letzter Beitrag vor 16 Jahren 1.751 Views
A
Adlervitriol Themenstarter:in
4 Beiträge seit 2008
vor 16 Jahren
Problem mit einem boolschen Ausdruck

Hallo,
ich hab ein Problem in einem größeren Zusammenhang, das ich auf folgende for-Schleife reduzieren konnte:



class Program
	{
		public static void Main(string[] args)
		{
			float end = 506.0F;
			float counter;
			float step = 50.6F;
			
			for( counter = 0; counter <= end; counter += step )
			{
				Console.WriteLine( counter );
			}
			
			Console.WriteLine();
			
			//ABER:
			
			end = 506.001F;
			
			for( counter = 0; counter <= end; counter += step )
			{
				Console.WriteLine( counter );
			}
			
			Console.WriteLine();
			Console.Write("Press any key to continue . . . ");
			Console.ReadKey(true);
		}
	}


Die Sache ist die: Führt man den Code aus, gibt die Console nur bis 455,4 aus, obwohl counter zum Schluss 506 beträgt (= end). Setzt man end etwas höher als 506, dann wird der Code erwartungsgemäß ausgeführt (vgl. 2. Schleife).

Hat jemand eine Idee, woran das liegen kann?

N
335 Beiträge seit 2006
vor 16 Jahren

Hallo Adlervitriol,

Das Verhalten ist völlig normal. Liegt an der begrenzten Genauigkeit von float.
Informiere dich mal, wie Fließkommazahlen dargestellt werden (Mantisse, etc.).

Versuche mal das hier:

            float end = 506.0F;
            float counter;
            float step = 50.6F;

            for( counter = 0f; (end - counter) >= float.Epsilon; counter += step )
            {
                Console.WriteLine( counter );
            }

Mfg NeuroCoder

185 Beiträge seit 2005
vor 16 Jahren

hallo,

aus dem bereits genannten grund ist es imho. eher ungewöhnlich, für for-schleifen eine float zahl als zählvariable zu verwenden - hab ich zumindest noch nie gebraucht => man sollte für sowas eher int verwenden.

fg
hannes

A
Adlervitriol Themenstarter:in
4 Beiträge seit 2008
vor 16 Jahren

Danke für den Hinweis mit der Genauigkeit, NeuroCoder. Leider ist zum Schluss end - counter < 0. Es funktioniert aber, wenn man counter als double deklariert. Entweder mache ich das, oder ich schreibe als Bedingung (end - counter) ≥ -0.001.

@HannesB:
counter ist eine Koordinate und der Wert wird im Körper der Schleife verwendet, deshalb brauche ich die Genauigkeit von float.

0
767 Beiträge seit 2005
vor 16 Jahren

rechne doch intern mit der genauigkeit von double. zurück auf float kommst du immer wieder.

loop:
btst #6,$bfe001
bne.s loop
rts

O
778 Beiträge seit 2007
vor 16 Jahren

50,6 ist hexadezimal gesehen ein unendlicher rationaler bruch, d.h., du kannst ihn nicht in einen endlichen datentyp quetschen, das wiederum heißt, es mag zwar vielleicht gehen, wenn du jetzt in diesem fall mit double arbeitest, aber du machst deine Software damit unnötig fehleranfällig. Benutz bei For-Schleifen immer int, wie du an die rankommst ist dir überlassen, aber du kannst die kontrollieren.