2010-10-19 15 views
18

Chcę użyć pętli for dla mojego problemu, a nie podczas. Czy można wykonać następujące czynności:dla pętli, przyrost o podwójne

for(double i = 0; i < 10.0; i+0.25) 

Chcę dodać podwójne wartości.

+2

Pamiętaj, że z powodu błędów zaokrągleń (o których mowa w mojej ocenie) najprawdopodobniej nie skończysz na ładnej rundzie. – Blindy

+2

Tak się składa, że ​​wszystkie wartości, jakie przyjmuje 'i' w twoim programie, są reprezentowane dokładnie jako wartości' double', ale jest to zły nawyk do pisania w pętli z indeksami zmiennoprzecinkowymi w ten sposób. Floating-point wymaga więcej opieki, jeśli nie chcesz widzieć dziwnych wyników. Zobacz na przykład http://www.mc.edu/campus/users/travis/syllabi/381/patriot.htm –

+2

@Blindy Na ten dokładny program, tak będzie. Dla nieco innego programu nie zrobiłby tego. –

Odpowiedz

46

Aby zapobiec ukąszeniu przez artefaktów arytmetyce zmiennoprzecinkowej, możesz użyć zmiennej pętli całkowitą i wyprowadzić wartość zmiennoprzecinkową potrzeba wewnątrz pętli:

for (int n = 0; n <= 40; n++) { 
    double i = 0.25 * n; 
    // ... 
} 
25

Zamiast tego można użyć i += 0.25.

+0

szukał tego! –

2
for(double i = 0; i < 10.0; i+=0.25) { 
//... 
} 

Dodany = wskazuje skrót dla i = i + 0,25;

6

odpowiedź James złapał najbardziej oczywisty błąd . Istnieje jednak subtelniejszy (i bardziej pouczający) problem z tym, że wartości zmiennoprzecinkowe nie powinny być porównywane dla (nie) równości.

Pętla ta jest podatna na problemy, należy użyć tylko liczby całkowitej i obliczyć podwójną wartość w pętli; lub, mniej elegancko, daj sobie trochę marginesu: for(double i = 0; i < 9.99; i+=0.25)

Edytuj: oryginalne porównanie działa poprawnie, ponieważ 0.25 = 1/4 to potęga 2. W każdym innym przypadku może nie być dokładnie reprezentowana jako liczba zmiennoprzecinkowa. Przykład (potencjalnych) problemu:

for(double i = 0; i < 1.0; i += 0.1) 
    System.out.println(i); 

drukuje 11 wartości:

0.0 
0.1 
0.2 
0.30000000000000004 
0.4 
0.5 
0.6 
0.7 
0.7999999999999999 
0.8999999999999999 
0.9999999999999999 
+1

Pierwotne pytanie ma "i <10.0". Czy możesz jeszcze raz wyjaśnić, w jaki sposób ma tu zastosowanie standardowe tłumaczenie na temat równości zmiennoprzecinkowej? (na marginesie, kiedy twoje obliczenia zmiennoprzecinkowe są dokładne, to całkowicie bezpieczne jest używanie równości). –

+0

"kiedy twoje obliczenia zmiennoprzecinkowe są dokładne" jest trudnym zdaniem.Ponieważ musisz mieć pewność, że twoje liczby dziesiętne przyjmują dokładną reprezentację w formacie liczb zmiennoprzecinkowych Java (0,25 zdarza się to przyznać, 0,2 lub 0,1 nie) dodałem przykład. – leonbloy

+0

Próbuję zrozumieć, jak dodanie 0.01 pomaga. Jeśli obliczenia nie są dokładne, wynik zmiennoprzecinkowy prawdopodobnie będzie poniżej rzeczywistego wyniku, jak powyżej, więc twoja "poprawka" może spowodować jedną dodatkową iterację w pętli, która ma już zbyt wiele iteracji w porównaniu do intencji programisty. –

2

W

for (double i = 0f; i < 10.0f; i +=0.25f) { 
System.out.println(i); 

F wskazuje float

Dodana = oznacza skrót dla i = i + 0,25;

0

Dla liczby całkowitej. Możemy użyć: for (int i = 0; i < a.length; i += 2)

for (int i = 0; i < a.length; i += 2) { 
      if (a[i] == a[i + 1]) { 
       continue; 
      } 
      num = a[i]; 
     } 

Tak samo możemy zrobić dla innych typów danych również.