1 / 2
May 2022

Witam,

Taka ciekawostka z prostego działu jakim jest “zaokrąglanie liczb”.
w uproszczeniu reguła jest taka, że gdy z prawej strony jest cyfra >= ‘5’, to wtedy należy dodać 1 do tej “liczby” z lewej.

Generalnie dąży się do tego, aby rożnica pomiędzy zaokrągloną liczbą a liczbą oryginalną była jak najmniejsza.

Przykład zaokrąglenia dla liczby: 1.123456789

1.123456789
1.12345679
1.1234568
1.123457
1.12346
1.1235
1.123
1.12
1.1
1

Nieścisłość pozostaje w przypadku, gdy z prawej strony jest ‘5’ + same ‘0’, czyli na przykład:

1.1250000000000 = 1.125
0.9150000000000 = 0.915

Wg tych zasad głównych, zaokrąglenie tych liczb do 2 miejsc po przecinku powinno wygladac tak:

1.13
0.92

Ku mojemu zdziwieniu poniższy program w C wygenerował inne wyniki:

#include <stdio.h>
#include <stdlib.h>
int main(void) {
  printf("%.2f\n", 1.125);
  printf("%.2f\n", 0.915);
  return EXIT_SUCCESS;
}

Wynik działania programu:

1.12
0.92

W zasadzie, z punktu widzenia rożnicy pomiędzy zaokrągloną liczbą a liczbą oryginalną, jest OK - to znaczy, ta różnica jest minimalna i wynosi 0.005 - tak więc chyba nie można mieć do tego “pretensji”.


Ta nieścisłość może pokazać problem w zadaniach, w których na wejściu podana jest wartość zaokrąglona, a zadanie polega na tym, aby wygenerować “wzór”, ktory w wyniku da tą właśnie liczbę.

Dla pokazania tego problemu weźmy liczbę oryginalną:

0.1234565

to jest nasz szukany wynik, musimy “wygenerować” taki “wzór”, aby go otrzymać.

W danych wejściowych w zadaniu będzie podany ten wynik w zaokrągleniu do 6 cyfr po przecinku:

0.123457

Jakiś program A wygeneruje wzór (poprawny):

wzór "A", ktory daje wynik 0.1234565
zaokrąglona wartość #1:    0.123456 (FAIL)
zaokrąglona wartość #2:    0.123457 (OK)

Inny program B wygeneruje inny wzór (niepoprawny):

wzór "B", który daje wynik 0.1234575
zaokrąglona wartość #1:    0.123457 (OK)
zaokrąglona wartość #2:    0.123458 (FAIL)

Dobrą odpowiedź da tylko program A (znalazł dobry wzór), o ile jego moduł “zaokrąglania” to #2.

Gdy Program B ma moduł “zaokrąglania” #1, będzie pewny, że jego odpowiedź jest poprawna.


Wydaje się, że tego problemu można się pozbyć, poprzez nie podawanie w danych wejściowych tak nieśćiśle zaokrąglonych liczb.


Pzdr.

  • created

    May '22
  • last reply

    May '22
  • 1

    reply

  • 430

    views

  • 2

    users

  • 2

    likes

  • 1

    link

Kiedyś już to tutaj przerabiałem i podawałem. Odesłał bym Cię do internetu, ale nie pamiętam gdzie. W każdym razie popatrz na to, jak jest aktualnie w “moim” Haskall’u:

narbej@debian:~$ ghci
GHCi, version 8.4.4: http://www.haskell.org/ghc/  :? for help

Prelude> round 3.5
4
Prelude> round 4.5
4
Prelude> round 5.5
6

Podobnie w pythonie:

narbej@debian:~$ python3
Python 3.7.3 (default, Jan 22 2021, 20:04:44) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> round(4.5)
4
>>> round(3.5)
4
>>> 

Jak jest w C/C++ sam wiesz?
W szkole uczono nas szkolnego zaokrąglania, ale w życiu jak to w życiu… :wink:
W różnym języku programowania może być różna metoda zaokrąglania, także zależnie od wersji kompiulatora, ale można wymusić/poprosić, aby program zaokrąglał tak jak chcemy.

W starym pythonie, było po staremu - po szkolnemu:

narbej@debian:~$ python
Python 2.7.16 (default, Oct 10 2019, 22:02:15) 
[GCC 8.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> round (3.5)
4.0
>>> round(4.5)
5.0
>>>