C++ 如何正确地迭代一个double

C++ 如何正确地迭代一个double,c++,loops,floating-point,double,C++,Loops,Floating Point,Double,我在重复t,就像这样 double dt = 0.1, t; double tmax = 100; for (t = 0; t <= tmax; t += dt) { /*do something*/ } 如果dt为0.1,如这里所示,一切都正常工作,并且在t=100时执行该步骤。但是如果我减少步骤,例如dt=0.001,则不会执行最后一步 我应该如何正确地迭代double?迭代整数,并使用开始步骤公式来获得每个double值 double dt = 0.1, t; double tma

我在重复t,就像这样

double dt = 0.1, t;
double tmax = 100;
for (t = 0; t <= tmax; t += dt) { /*do something*/ }
如果dt为0.1,如这里所示,一切都正常工作,并且在t=100时执行该步骤。但是如果我减少步骤,例如dt=0.001,则不会执行最后一步


我应该如何正确地迭代double?

迭代整数,并使用开始步骤公式来获得每个double值

double dt = 0.1, t;
double tmax = 100;
int i, n = (int)(tmax / dt); // n: check your rounding or specify explicitly.
for (i = 0; i <= n; i++) { t = 0/*start*/ + dt * i; /*do something*/ }

迭代一个整数,并使用开始步骤公式获得每个双精度值

double dt = 0.1, t;
double tmax = 100;
int i, n = (int)(tmax / dt); // n: check your rounding or specify explicitly.
for (i = 0; i <= n; i++) { t = 0/*start*/ + dt * i; /*do something*/ }

您的代码很好,行为符合预期。好的,不是预期的,但可以解释,因为浮点数是如何工作的。看看这里,万一有一天链接消失,谷歌程序员应该知道什么关于浮点-我肯定它会被缓存在某个地方

您的代码很好,行为符合预期。好的,不是预期的,但可以解释,因为浮点数是如何工作的。看看这里,万一有一天链接消失,谷歌程序员应该知道什么关于浮点-我肯定它会被缓存在某个地方

而不是

for (t = 0; t <= tmax; t += dt) { /*do something*/ }
而不是

for (t = 0; t <= tmax; t += dt) { /*do something*/ }

我认为第三行的n和第四行的nt应该是相同的标识符。谢谢。我没有注意到。另外,我使用了错误的比较,我认为第三行中的n和第四行中的nt应该是相同的标识符。谢谢。我没有注意到。此外,我使用了错误的比较更多的文献:最小化准确性问题的影响更多的文献:最小化准确性问题的影响不允许仲裁。如果dt是Math.PI/10呢?实例:绘制一个20-gon@MarkJeronimus你的答案有一个系统性的偏差,因为它总是对包含i*0.1的t“做点什么”,而意图是i/10。在问题的条件下可以避免这种系统性偏差,因为10、100和1000是完全可以表示的。当dt及其逆都不可精确表示时,最简单的解决方案是使用乘法。无论i是什么整数,在1/dt为理想整数的情况下,i*dt始终是最接近理想值的IEEE-754浮点。如果dt=1/10,则与i*10完全相同。@MarkJeronimus No:3*0.1!=3 / 10.0. 后者是0x1.3333P-2,前者是0x1.3334P-2。后者是一个更好的近似值。@MarkJeronimus,这要视情况而定。这可能是巧合的情况,π/10非常接近一个双倍体,比π相对最近的双倍体更接近。在这种情况下,直接使用π/10的双精度比尝试复杂的技巧要好。这不允许仲裁dt。如果dt是Math.PI/10呢?实例:绘制一个20-gon@MarkJeronimus你的答案有一个系统性的偏差,因为它总是对包含i*0.1的t“做点什么”,而意图是i/10。在问题的条件下可以避免这种系统性偏差,因为10、100和1000是完全可以表示的。当dt及其逆都不可精确表示时,最简单的解决方案是使用乘法。无论i是什么整数,在1/dt为理想整数的情况下,i*dt始终是最接近理想值的IEEE-754浮点。如果dt=1/10,则与i*10完全相同。@MarkJeronimus No:3*0.1!=3 / 10.0. 后者是0x1.3333P-2,前者是0x1.3334P-2。后者是一个更好的近似值。@MarkJeronimus,这要视情况而定。这可能是巧合的情况,π/10非常接近一个双倍体,比π相对最近的双倍体更接近。在这种情况下,直接使用π/10的双精度比尝试复杂的技巧要好。对于t=0,怎么办;t