Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [biblioteka] Rounder, Czyli jak round() wywołało frustrację
greycoffey
post
Post #1





Grupa: Zarejestrowani
Postów: 320
Pomógł: 29
Dołączył: 3.04.2010

Ostrzeżenie: (20%)
X----


Hej,

sfrustrowany dzisiaj zachowaniem funkcji round() której zaokrąglanie half up i half down nie jest tym, za co się podaje, spłodziłem klasę, która robi to poprawnie. Zawiera interfejs oraz domyślną implementację zaokrąglacza, druga implementacja (oparta na bcmath) właśnie się tworzy (co do tego, macie jakiś pomysł na implementację metod roundHalfEven() i roundHalfOdd() w Pamil\Rounder\BcmathRounder w gałęzi bcmath-support?).

Przykład użycia i kod na GitHubie.
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
Crozin
post
Post #2





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Cytat
Interfejsy są po to, żeby móc skorzystać z danego typu implementacji na różne sposoby.
Interfejsy są po to by korzystać z różnych implementacji w ten sam sposób. To o czym piszesz w dalszej części postu w tym konkretnym przypadku jest błędne. Tutaj chcemy mieć obiekt, który będzie potrafił wykonywać różnego rodzaju zaokrąglenia (w sumie 11 sposobów) na różnych podmiotach (zwykła liczba czy BC Math) i interfejs służy właśnie do wyizolowania tych podmiotów, nie samych metod zaokrąglania. Interfejs kalkulatora, który podałeś również jest błędny. Każdy kalkulator powinien umieć dodać czy odejmować. Przedstawiony przez Ciebie interfejs powinien nazywać się Operation czy właściwie BinaryOperation (od dwóch argumentów, nie od danych binarnych).
Cytat
Albo mogę zwracać ten sam wynik, ale np. jedno kosztem drugiego. Przykład: jest sobie klasa, która działa szybko, ale liczy liczby do jakiegoś MAX_INT oraz druga, która jest wolniejsza, ale liczy też ogromne liczby.
Tutaj już podałeś poprawny przykład.
Cytat
Inna implementacja po prostu nie ma sensu, bo zwracanie randoma to zwracanie randoma. Tu się nic nie wymyśli. A że mt_rand() działa szybciej, jest w tym przypadku jedyną słuszną implementacją, w związku z tym wystarczy: [...]
Tutaj znowu błąd. mt_rand nie jest jedyną słuszną implementacją w tym wypadku. Przecież mogę potrzebować takiej implementacji, która zawsze zwróci 42 albo jakiś z góry określony cykl liczb na przykład na potrzeby testów. Albo taką, która będzie w przeciwieństwie do mt_rand generować kryptograficznie bezpieczną liczbę. Albo jeszcze inną, która zwróci inny rozkład losowych liczb dla danego przedziału.

Cytat
Na tym polega cały nonsens takich przedsięwzięć, że więcej czasu zajmuje pisanie durnych testów jednostkowych i tworzenie repozytorium na GitHubie niż właściwe pisanie kodu.
Ale to, że taki kod da się później normalnie wykorzystywać w innych projektach już nie napiszesz.
Cytat
Ten interfejs to też sobie można gdzieś wsadzić bo wystarczy abstrakcyjna klasa, która sama w sobie stanowi interfejs.
Klasa abstrakcyjna raczej nie powinna stanowić publicznego interfejsu w językach z pojedynczym dziedziczeniem. Na pewno nie w tym konkretnym przypadku.
Go to the top of the page
+Quote Post
pyro
post
Post #3





Grupa: Zarejestrowani
Postów: 2 148
Pomógł: 230
Dołączył: 26.03.2008

Ostrzeżenie: (0%)
-----


Cytat(Crozin @ 6.01.2014, 16:42:57 ) *
Interfejsy są po to by korzystać z różnych implementacji w ten sam sposób. To o czym piszesz w dalszej części postu w tym konkretnym przypadku jest błędne. Tutaj chcemy mieć obiekt, który będzie potrafił wykonywać różnego rodzaju zaokrąglenia (w sumie 11 sposobów) na różnych podmiotach (zwykła liczba czy BC Math) i interfejs służy właśnie do wyizolowania tych podmiotów, nie samych metod zaokrąglania. Interfejs kalkulatora, który podałeś również jest błędny. Każdy kalkulator powinien umieć dodać czy odejmować. Przedstawiony przez Ciebie interfejs powinien nazywać się Operation czy właściwie BinaryOperation (od dwóch argumentów, nie od danych binarnych).


Kurcze, już w momencie pisania tamtego postu przeczuwałem, że ktoś przyczepi się do tych przykładów i zarzuci branie ich za autorytet lub jakiś w pełni funkcjonalny przykład. Czułem, że pownienem był napisać jakieś ostrzeżenie czy coś (IMG:style_emoticons/default/wink.gif) . Pragnę więc oświadczyć Tobie, jak i potomnym, że z praktycznego punktu widzenia żadna z powyższych klas nie ma sensu i służyła tylko przedstawieniu toku myśleniowego "dlaczego tak a nie inaczej". Zostało to zresztą "pisane na kolanie", co widać chociażby po braku wcięć (Notepad++). Coś na styl kaczek, piesków, kotków z dajGlos(); (przykład często widziany w internecie).

Cytat(Crozin @ 6.01.2014, 16:42:57 ) *
Tutaj znowu błąd. mt_rand nie jest jedyną słuszną implementacją w tym wypadku. Przecież mogę potrzebować takiej implementacji, która zawsze zwróci 42 albo jakiś z góry określony cykl liczb na przykład na potrzeby testów. Albo taką, która będzie w przeciwieństwie do mt_rand generować kryptograficznie bezpieczną liczbę. Albo jeszcze inną, która zwróci inny rozkład losowych liczb dla danego przedziału.


W sumie wybrałem trochę kiepski przykład na przedstawienie problemu. Nie mniej specjalnie podałem tylko dwie klasy i cały czas pisałem dlaczego w tym przypadku jedna wyklucza drugą i dlaczego tylko odnosić się tylko do tego, co zostało napisane.
Cytat(pyro)
Obie klasy pozwalają na generowanie randomowych liczb, ale wyliczono, że mt_rand() działa ok. 4 razy szybciej. Inna implementacja po prostu nie ma sensu, bo zwracanie randoma to zwracanie randoma. Tu się nic nie wymyśli. A że mt_rand() działa szybciej, jest w tym przypadku jedyną słuszną implementacją


bo takie rzeczy jak losowanie z przedziału liczb w ogóle nie zostały tu po prostu przedstawione. Ale tak jak wspomniałem - przykład rzeczywiście nie najlepszy. Załóżmy, że dla tego przykładu nie istnieją dodatkowe założenia jak możliwość generowanie kryptograficznie bezpiecznej liczby albo testów. Zachęcam w międzyczasie do napisania lepszego przykładu z powodów przedstawionych.
Go to the top of the page
+Quote Post

Posty w temacie
- greycoffey   [biblioteka] Rounder   30.12.2013, 21:28:35
- - gitbejbe   wygląda fajnie, klasa czytelna i zrozumiała. Choci...   31.12.2013, 10:44:49
- - pyro   Wygląda na sensownie skonstruowany kawałek kodu. N...   31.12.2013, 12:10:41
- - destroyerr   Cytatsfrustrowany dzisiaj zachowaniem funkcji roun...   31.12.2013, 12:49:04
- - greycoffey   @gitbejbe, trafiłeś w sedno, czas napisać coś, co ...   31.12.2013, 12:58:25
- - destroyerr   @greycoffey przekonałeś mnie. Za bardzo skupiłem s...   31.12.2013, 13:39:17
- - gitbejbe   @pyro zastosowanie interfejsów i abstrakcji też m...   31.12.2013, 14:52:56
- - greycoffey   @destroyerr, masz rację, przerobiłem Roundera na m...   31.12.2013, 17:09:16
- - Crozin   Drobne uwagi: - implements RounderInterface możesz...   31.12.2013, 17:45:35
- - pyro   Cytat(greycoffey @ 31.12.2013, 12:58...   31.12.2013, 18:20:46
- - lukasz1985   Na tym polega cały nonsens takich przedsięwzięć, ż...   6.01.2014, 16:02:33
- - com   @up to możesz dać choć jeden sensowny powód poco t...   6.01.2014, 16:20:49
- - Crozin   CytatInterfejsy są po to, żeby móc skorzystać z da...   6.01.2014, 16:42:57
|- - pyro   Cytat(Crozin @ 6.01.2014, 16:42:57 ) ...   6.01.2014, 17:26:11
- - lukasz1985   "Klasa abstrakcyjna raczej nie powinna stanow...   8.01.2014, 13:23:34
- - emp   Cytat(Crozin)Klasa abstrakcyjna raczej nie powinna...   8.01.2014, 13:40:38
- - Crozin   CytatKurcze, już w momencie pisania tamtego postu ...   9.01.2014, 11:10:46
- - lukasz1985   Naprawdę wątpię, żeby komuś chciało się do zaokrąg...   9.01.2014, 19:06:15
- - Crozin   CytatNaprawdę wątpię, żeby komuś chciało się do za...   9.01.2014, 19:31:40
- - greycoffey   Hej, ogarnąłem się po sylwestrze także mogę odpowi...   9.01.2014, 20:51:53


Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 12.10.2025 - 10:10