Verwendung von double als Zählervariablen in Schleifen

Verwendung von double als Zählervariablen in Schleifen


In einem Buch, das ich gerade lese, gibt es diesen Auszug:



Kann bitte jemand erklären, wie der erste Codeblock läuft, während der zweite nicht?


Antworten:


Der erste wird schließlich beendet, auch wenn x erreicht nicht genau 2.0 ... weil es am Ende größer wird als 2.0 und damit ausbrechen.


Der zweite müsste x machen traf genau 1.0, um zu brechen.


Es ist bedauerlich, dass das erste Beispiel einen Schritt von 0,25 verwendet, was genau in binären Gleitkommazahlen darstellbar ist - es wäre klüger gewesen, beide Beispiele mit 0,2 als Schrittgröße zu verwenden. (0,2 ist in binären Gleitkommazahlen nicht genau darstellbar.)


Einige Code-Antworten


double a(0.3), b(2.5);
for(double x = 0.0;
x <= 2.0;
x += 0.25)
cout <<
"\n\tx = " <<
x <<
"\ta*x + b = " <<
a*x + b;
for(double x = 0.0 ;
x != 1.0 ;
x += 0.2)
cout <<
x;
double x(0.0);
// do some work that may or may not set up x if (x != 0.0) {
// do more work }
double x(0.0);
double target(10000.0);
double tolerance(0.000001);
// do some work that may or may not set up x to an expected value if (fabs(target - x) <
tolerance) {
// do more work }
// using System.Diagnostics;
double a = 0.2;
a *= 5.0;
double b = 1.0;
Debug.Assert(a == b);
Debug.Assert(Math.Abs(a - b) <
0.0001);