problem chyba z nieskoczoncza petla

problem chyba z nieskoczoncza petla
L4
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1
0
Kopiuj
#include <stdio.h>

int main() {
    for (float i = 0; i != 1; i += 0.1) {
        printf("%f\n", i);
    }
    return 0;
}

Czemu pętla nigdy się nie kończy?

tBane
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Poznań
  • Postów: 538
4

Pewnie chodzi o precyzję floata. Spróbuj tak:

Kopiuj
#include <stdio.h>

int main() {

  for (float i = 0.0f; i <= 1.0f; i += 0.1f) {
    printf("%f\n", i);
  }

  return 0;
}
B1
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 489
5

Bo dodanie 10x 0.1 nie wynosi w c++ 1, można sobie sprawdzić takim kodem

Kopiuj
int main() {
    float a = 0;
    for (float i = 0; i < 10; i ++) {
        a += 0.1;
    }
    printf(a != 1 ? "Dodanie 10x 0.1 jest różne od 1" : "Dodanie 10x 0.1 jest równe 1");
    return 0;
}

Ewentualnie do Twojego kodu dodać warunek i < 2 i wyświetlać dłuższe rozwinięcie

Kopiuj
int main() {
    for (float i = 0; i != 1 && i < 2; i += 0.1) {
        printf("%.23f\n", i);
    }
    return 0;
}

Wtedy widać że 0.1 to jest tak naprawdę 0.10000000149011611938477

Ogólnie iteracje po floatach i doublach to zły pomysł, kolega wrzucił wyżej przykład

Kopiuj
  for (float i = 0.0f; i <= 1.0f; i += 0.1f) {
    printf("%f\n", i);
  }

może się wydawać na pierwszy rzut oka że ostatnie się wypisze 1.000000, ale ostatnie jest 0.900000 ze względu na to o czym pisałem wyżej

MarekR22
  • Rejestracja: dni
  • Ostatnio: dni
2

Liczby zmiennoprzecinkowe mają skończoną dokładność.
Dodawanie 0.1 binarnie, to coś jak dodawanie 1/3 w systemie dziesiętnym 0.333 + 0.333 + 0.333 = 0.999 a nie 1.0.
Tak jak 1/3 nie da się zaprezentować dokładnie w systemie dziesiętnym, tak 1/10 nie da się dokładnie zaprezentować w systemie binarnym.

Efekt jest taki, że operatory == i != mają ograniczone zastosowanie dla liczb zmiennoprzecinkowych.
Po obliczaniach trzeba uwzględnić jakąś tolerancję. Najbardziej ścisła metoda:

Kopiuj
#include <float.h>
#include <stdio.h>

int main() {
    for (float i = 0.0f; i < 1.0f - 0.1 * 3 * FLT_EPSILON; i += 0.1f) {
        printf("%f\n", i);
    }

    return 0;
}

https://godbolt.org/z/KWvYq63jG

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.