我有一个起点和终点,我想使用特定的步长循环它们,但我需要确保包含终点。以下是实现这一目标的最佳方法,还是有更好的方法?
Double start = 2.1;
Double end = 5.3;
Double step = 0.6;
for(Double i = start; i <= end; i += step) {
// do stuff
if(i != end && (i + step) > end) {
i = end;
}
}
答案 0 :(得分:3)
您可以使用循环外的指令来执行end
部分。
不要在迭代中使用double
。由于存储浮点数的方式,您可以2.1 +0.6
为2.7
,但as 2.69999999999999999999
。在这种情况下,乘以10即可达到你想要的效果。
你的解决方案是错误的。你让i = end,但是它会逐步添加,所以你不要迭代。你可以使用:
if(i != end && (i + step) > end) {
i = end-step;
}
答案 1 :(得分:1)
通常,您应该更喜欢循环变量的整数,尤其是当区间除以整个步数时。如果不可能,你可以使用double值,但是你需要小心避免双重计算的精确陷阱。
比较双打的平等并不是一个好主意。更好的方法是使用Math.min来限制end的值:
for(double i = start; i < end+step; i += step) {
double pt = Math.min(end, i);
... // use pt here
}
答案 2 :(得分:0)
您可以计算所需的整数步数,并使用它们来控制循环。当您到达最后一步时,请使用end
值。
public static void main(String[] args)
{
Double start = 2.1;
Double end = 5.3;
Double step = 0.6;
int steps = (int)Math.round((end-start)/step);
if(start + steps*step < end) steps++;
double pos = start;
for(int s=0; s<=steps; )
{
System.out.println(pos);
s += 1;
pos = (s==steps) ? end : start + step*s;
}
}
输出:
2.1
2.7
3.3
3.9
4.5
5.1
5.3
请注意,对于中间步骤,我们使用乘法而不是重复加法来计算位置。我目前无法找到参考资料,但我的理解是,这会导致浮动点减少而且漂移不足。这似乎得到了证实。如果我们使用:
pos = (s==steps) ? end : pos+step;
计算下一个pos
然后我们得到输出:
2.1
2.7
3.3000000000000003
3.9000000000000004
4.5
5.1
5.3