Otóż piszę program, który liczy sufit z różnicy dwóch liczb całkowitych podzielonych również przez całkowitą. Jako, że zrobienie tego na samych intach nie wchodzi w grę, bo C++ uznaje, że wynik działania na intach będzie intem i mamy np. 22/10=2, postanowiłem to zrobić na floatach. Problem jednak pojawi się przy odejmowaniu - zdaniem tak napisanego algorytmu 109 -1=109. Spowodowane jest to, jak sądzę, przybliżoną naturą typów zmiennoprzecinkowych. Jaki jest najbardziej optymalny sposób wyjścia z tego? Czy jest coś lepszego niż wczytanie dwóch pierwszych zmiennych (odjemnej i odjemnika) jako intów, zrobienie odejmowanie na intach, a potem konwersja na float i podzielenie przez trzecią liczbę, wczytaną jako float w trakcie "sufitowania"?
Myślę, że do tego nie potrzeba żadnych floatów. Jeśli chcesz mieć sufit, to przy dzieleniu całkowitym zaokrąglaj w górę:
ceil(x / y) = (x - 1) / y + 1
Rewelacja, właśnie o takie coś chodziło. Dzięki wielkie :)
A jeszcze pytanie o floaty z podobnej kategorii.. Czy dziwne wyniki są tylko przy działaniach z dwoma floatami/floatem i intem? Czy kiedy do gry wchodzi stała to już nie ma się czego obawiać i jakieś mnożenie floata przez liczbę całkowitą czy dzielenia będzą zawsze dawać normalny wynik czy czasem może się wykrzaczyć? W jednym zadaniu zamierzam wykorzystać zapisanie we float'cie mnożenia inta przez stałą i nie wiem, czy to jest bezpieczne. Jak na razie działa dobrze, ale kilka prób może być mylących.
To zależy. Float (i double) jako typ zmiennoprzecinkowy o skończonej precyzji prawie zawsze da tylko przybliżoną dokładność. Stała może mieć inną wartość po sparsowaniu niż tą, którą się wpisało.
http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems
zamiast float
a użyj double
. ma większą dokładność.
nie ma znaczenia czy masz zmienne czy stałe, chociaż kompilator może stałe traktować domyślnie jako double (nie wiem co standard na to)
w każdym razie zawsze typy zmiennoprzecinkowe należy traktować jako przybliżone: wystarczająco dokładne do większości obliczeń praktycznych, ale czasami wykazujące takie anomalie, zwłaszcza przy dodawaniu i odejmowaniu.
Powinieneś sobie poczytać o obliczeniach zmiennoprzecinkowych i stabilności algorytmów numerycznych. Jak masz czas, to ogarnij sobie jakąś książkę do programowania numerycznego, np. Actona (trochę stara, ale dość przystępna).
Dzięki wielkie za odpowiedzi. Postaram się coś przeczytać, chociaż biorąc pod uwagę zapas czasu, pewnie nie przeczytam. O książce na tak wąski temat niestety nie ma mowy.