devilmateo Temat założony przez niniejszego użytkownika |
Pętla for i liczby zmiennoprzecinkowe » 2011-08-27 01:24:01 Witam. Bawię się pętlą for i zastanawia mnie jeden fakt. Dlaczego w przypadku: for( float k = 1.0; k <= 2.0; k += 0.1 ) { std::cout << k << ","; } Pętla podaje jako ostatnią wartość k=1.9. A w przypadku gdy krok wynosi np.0.01, to ostatnią wartością w pętli jest 2. Proszę o pomoc. |
|
akwes |
» 2011-08-27 01:36:52 A zastanów się dlaczego: float a = 2.0; double b = 2.0;
if( a == b ) cout << "TAK!"; else cout << "NIE!";
Wyświetla TAK!
Natomiast float a = 1.9; double b = 1.9;
if( a == b ) cout << "TAK!"; else cout << "NIE!";
Wyświetla NIE!
A podpowiem że chodzi o reprezentacje liczb zmiennoprzecinkowych w pamięci komputera. |
|
|
devilmateo Temat założony przez niniejszego użytkownika |
» 2011-08-27 07:22:32 Podałeś float i double więc u Ciebie wystarczy że zamienię na double obie liczby i działa poprawnie. Wiem, że float i double mają inny rozmiar w bajtach. Ale ja użyłem tylko float, a jak zmieniłem na double to mam ten sam efekt dziwnego liczenia. |
|
imralav |
» 2011-08-27 07:25:25 Może spróbuj dodać 'f' za wartościami zmiennych: |
|
devilmateo Temat założony przez niniejszego użytkownika |
» 2011-08-27 07:30:02 Niestety dalej to samo. I ja tam miałem k<=2.0. A czy u Ciebie podaje dobrze wartość ta procedura? |
|
imralav |
» 2011-08-27 07:49:08 Z tamtym dodawaniem 'f' w ciemno strzelałem ; p Czasem w SFML pomagało.. Zaraz sprawdzę kod u siebie.
#edit: Kombinuję,ale cienki jeszcze jestem w te klocki, to moją wiedzę przekracza trochę.. Wybacz. |
|
akwes |
» 2011-08-27 13:45:40 Tak, są różne typy, ale chciałem Ci pokazać przykład wywołany tym samym zagadnieniem i napomnieć że Niektóre liczby zmiennoprzecinkowe nie dają się zapisać w pamięci w postaci zer i jedynek, dlatego przyjmuje się ich dość bliskie przybliżenia, które po obliczeniu wartości binarnej z wartości dziesiętnej są niedokładnym odwzorowaniem tej liczby |
Czyli np. Float, który ma zakres do 7 cyfr, liczby 1.9 nie reprezentuje jako "1.9000000" tylko np. "1.9000001". Dlatego I co z tego wynika? A no to że o ile 1.9000000 + 0.100000 = 2.000000 ale 1.9000001 + 0.100000 = 2.000001 Sprawia że a nie jest równe 2.0, ale większe. Skąd problem z Double i Float w porównaniu? Liczba 1.9 jest liczbą felerną i jej rozwinięcie nawet dla Double nie daje się zapisać całkowicie (część ułamków ma jak gdyby nieskończone rozwinięcie dziesiętne (binarne?). Dlatego dla double może to być: 1.90000000000001 i to również nie będzie równe dla Float 1.9 bo Float 1.9 było: 1.9000001 a sam widzisz, które jest większe 1.90000010000000 1.90000000000001 (dla estetyki przy float dodałem zero). Tylko teraz, wszystkie liczby które podałem są przykładowe, więc może występować zupełnie inna reprezentacja danych w pamięci, ale podaję tutaj ogólną zasadę i powód takich niuansów. To nie wada języka C++, tylko binarnej reprezentacji liczb zmiennoprzecinkowych. |
|
devilmateo Temat założony przez niniejszego użytkownika |
» 2011-08-27 15:11:47 Dziękuję za wyjaśnienie. Chciałbym tylko jeszcze wiedzieć, co mam zrobić, żeby w pętli for występujący if porównał "i" z 0.8, i wypluł napis "cokolwiek". Skoro to nie jest 0.8 w związku z Twoją argumentacją, to jak to mogę obejść żeby uparcie to 0.8 otrzymać. Nie chciałbym mieć takich problemów w przyszłości. for( i = 0.0; i <= 1.0; i += 0.1 ) { if( i == 0.8 ) { std::cout << "cokolwiek"; } } |
|
« 1 » 2 |