![]() |
![]() ![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 1 045 Pomógł: 5 Dołączył: 8.11.2004 Skąd: trójmiasto Ostrzeżenie: (0%) ![]() ![]() |
|
|
|
![]()
Post
#2
|
|
Grupa: Zarejestrowani Postów: 219 Pomógł: 5 Dołączył: 18.07.2006 Skąd: Piekary Śląskie Ostrzeżenie: (0%) ![]() ![]() |
W sumie dziwne bo jak za $liczba podstawi się 50 to jest OK.
Podejrzewam, że na naszych niedoskonałych procesorach 7/0.14 = 49.999999999999999999 (to tylko przykład). Zwykłe wyświetlanie wyniku pewnie zaokrągla na którymś miejscu po przecinku i wychodzi 50. Natomiast floor pewnie bierze całą liczbę i zaokrągla w dół. Aczkolwiek sprawa ciekawa. W wolnej chwili zobaczę jak to wygląda w innych językach i kompilatorach. |
|
|
![]()
Post
#3
|
|
Grupa: Zarejestrowani Postów: 121 Pomógł: 4 Dołączył: 9.06.2007 Skąd: Kielce Ostrzeżenie: (0%) ![]() ![]() |
a musisz koniecznie wykorzystywać floor? nie mozesz np spróbować round()?
|
|
|
![]()
Post
#4
|
|
Grupa: Zarejestrowani Postów: 1 045 Pomógł: 5 Dołączył: 8.11.2004 Skąd: trójmiasto Ostrzeżenie: (0%) ![]() ![]() |
round to nie floor,
ale chyba potraktuje to strpos i substr |
|
|
![]()
Post
#5
|
|
Grupa: Zarejestrowani Postów: 219 Pomógł: 5 Dołączył: 18.07.2006 Skąd: Piekary Śląskie Ostrzeżenie: (0%) ![]() ![]() |
Kod C#, kompilator VS .Net 2005, procesor Intel Centrino, system Windows XP Professional
Wynik:
Kod C++, kompilator VS .Net 2005, procesor Intel Centrino, system Windows XP Professional
Wynik:
Pod Demianem pracującym na AMD Athlonie XP 2500+ kod w C++ daje taki sam zły wynik. Ten post edytował cicik 8.08.2007, 08:17:53 |
|
|
![]()
Post
#6
|
|
Grupa: Zarejestrowani Postów: 561 Pomógł: 75 Dołączył: 19.08.2004 Skąd: Wrocław Ostrzeżenie: (0%) ![]() ![]() |
Analogie to powyższego przykładu spotkałem w literaturze swego czasu. Błąd faktycznie bierze się z niedoskonałości liczenia procesorów, jest nie do wyeliminowania drogą bezpośrednią, wynik zawsze będzie błędny.
|
|
|
![]()
Post
#7
|
|
Grupa: Zarejestrowani Postów: 219 Pomógł: 5 Dołączył: 18.07.2006 Skąd: Piekary Śląskie Ostrzeżenie: (0%) ![]() ![]() |
Pewnie kluczem do rozwiązania zagadki jest to, że liczba 0.1 jest liczbą niewymierną w systemie dwójkowym, a 0.14 = 0.1 + 0.04.
Procesory stosują różne triki, żeby tę cechę wyeliminować ale jak widać nie zawsze działa. Aczkolwiek kiedyś miałem taki problem, że pisałem program do obliczania jakimi monetami wydać resztę w sklepie (na jakiś konkurs to było). Chodziło to aby badać reszty z dzielenia. No i generalnie na Intelach wyniki dzielenia (albo zaokrąglania - to dawno było) były inne od tych uzyskanych na AMD - tym samym kodem źródłowym!!! To mnie wtedy dość mocno zaskoczyło bo procesory przechodzą bardzo ostre testy na poprawność działania jednostki arytmetycznej, zwłaszcza tej zmiennoprzecinkowej. Historia o tym jak kiedyś wybuchła jakaś rakieta kosmiczna bo któryś Pentium źle liczył jest dość znana. Ten post edytował cicik 8.08.2007, 09:17:08 |
|
|
![]()
Post
#8
|
|
Grupa: Zarejestrowani Postów: 175 Pomógł: 17 Dołączył: 23.06.2006 Ostrzeżenie: (0%) ![]() ![]() |
Problem polega wlasnie na tym co mowil moj poprzednik, aby ten temat sobie blizej przyblizyc, nalezy poczytac o tym, jak binarnie sa kodowane liczby po przecinku i mowa tu o liczbach zmiennoprzecinkowych. Cala sprawa kreci sie wtedy wokol kodowania FP2.
Na szybko mowiac, dla przykladu mamy taki ciag binarny (podzielony na grupy): 1|101|100101 liczba w pierwszej grupie jest to znak (+/-) liczby w drugiej jest to cecha, inaczej zakres liczby liczby w trzeciej grupie to mantysa, jest to tak naprawde nasza liczba, tyle ze zamieniona tak, zeby byla po przecinku Jest wzór, wg którego obliczamy (odkodowujemy) liczbę zawartą w tym kodzie, ale ze względu na użyte potęgi, nie podałem go tu, a więc zainteresowanych odsyłam do google.pl Chodzi o to, ze im mamy część całkowitą dalszą od zera, tym jej wartość po przecinku staje sie mniej dokladna i coraz bardziej zaokraglana wraz ze zwiększaniem tej odległości. Co do problemu postawionego w tym poście, mam rozumieć, że w obu przypadkach chcemy uzyskać liczbę 50? |
|
|
![]()
Post
#9
|
|
Grupa: Zarejestrowani Postów: 23 Pomógł: 0 Dołączył: 24.07.2006 Ostrzeżenie: (0%) ![]() ![]() |
Oto kod
Który wyświetla mi 50 49 Jakoby zaokrągleniem w dół liczby 50 było 49! Czy ktoś wie dlaczego mi tak robi i jak to ominąć. Na szybko może tak:
Wynik: 50 50 Musiałbyś jedynie dobrze dobrać dokładność zaokrąglenia. |
|
|
![]()
Post
#10
|
|
Grupa: Przyjaciele php.pl Postów: 698 Pomógł: 3 Dołączył: 28.03.2004 Skąd: Wrocław Ostrzeżenie: (0%) ![]() ![]() |
To nie ma sensu. Liczba 50.6 zostanie zaokrąglona do 51, a nie o to chodzi.
php programmer: Próbowałeś rzutowania na integer? Rzuć okiem, ja w tej chwili nie mam jak tego sprawdzić... |
|
|
![]()
Post
#11
|
|
Grupa: Zarejestrowani Postów: 23 Pomógł: 0 Dołączył: 24.07.2006 Ostrzeżenie: (0%) ![]() ![]() |
To nie ma sensu. Liczba 50.6 zostanie zaokrąglona do 51, a nie o to chodzi. php programmer: Próbowałeś rzutowania na integer? Rzuć okiem, ja w tej chwili nie mam jak tego sprawdzić...
Wynik: 50.6 50 Przez to pisałem o dokładności zaokrąglenia. Pozdrawiam Kosmi |
|
|
![]()
Post
#12
|
|
Grupa: Zarejestrowani Postów: 189 Pomógł: 0 Dołączył: 4.07.2004 Skąd: z neostrady Ostrzeżenie: (0%) ![]() ![]() |
To nie ma sensu. Liczba 50.6 zostanie zaokrąglona do 51, a nie o to chodzi. Jakie 50.6? Tam jest zaokrąglanie z dokładnością do 6 miejsc po przecinku. I wydaje się to być dobrym pomysłem. Poza tym dodam jeszcze od siebie - zamienić dzielenie na mnożenie:
50 50 |
|
|
![]() ![]() |
![]() |
Aktualny czas: 24.08.2025 - 01:33 |