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
pyro
post
Post #2





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

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


Cytat(greycoffey @ 31.12.2013, 12:58:25 ) *
@pyro, co do tej abstrakcji, w planach mam dodanie obsługi zaokrąglania dla dużych liczb (i to można wykonać za pomocą bcmath, lub własnego algorytmu, w każdym razie będzie to obsługa dużych liczb w postaci łańcuchów znaków, nie liczb).

Interfejsy - dla swobodnego dodawania i wymieniania implementacji.
Klasa abstrakcyjna - by nie pisać powtarzalnej metody round($number, $precision, $roundingMode) w implementacjach



Cytat(gitbejbe @ 31.12.2013, 14:52:56 ) *
@pyro

zastosowanie interfejsów i abstrakcji też mnie zastanowiło. Faktycznie kod jest bardziej pro i wymusza on schematy działania, ale czy nie jest to przyrost treści nad formą ? Tak naprawdę do każdego rodzaju zaokrąglenia wystarczy napisać samą metodę w której jest tylko to co trzeba. Każdy jednak ma swoją wizje, do Twojej tak czy siak trudno się przyczepić. Dobra robota !


Chyba się trochę nie zrozumieliśmy. Interfejsy są po to, żeby móc skorzystać z danego typu implementacji na różne sposoby. Przykładowo na podstawie danego interfejsu mogę zwracać różne wyniki, np:

  1. <?php
  2.  
  3. class Calculator {
  4.  
  5. private $a;
  6. private $b;
  7. private $strategy;
  8.  
  9. public function __construct($a, $b) {
  10. $this->a = $a;
  11. $this->b = $b;
  12. }
  13.  
  14. public function setStrategy($strategyName) {
  15. $className = ucfirst(strtolower($strategyName));
  16.  
  17. if(class_exists($className) && is_subclass_of($className, 'CountingStrategy')) {
  18. $this->strategy = new $className();
  19. return true;
  20. } else {
  21. throw new StrategyNotFoundException('Calculation type not found');
  22. }
  23. }
  24.  
  25. public function calculate() {
  26. $this->strategy->setVariables($a, $b);
  27. return $this->strategy->getResult();
  28. }
  29.  
  30. }
  31.  
  32. abstract class CountingStrategy {
  33. private $a;
  34. private $b;
  35.  
  36. abstract public function getResult();
  37. public function setVariables($a, $b) {
  38. $this->a = $a;
  39. $this->b = $b;
  40. }
  41. }
  42.  
  43. class Sum extends CountingStrategy {
  44. public function getResult() {
  45. return $this->a + $this->b;
  46. }
  47. }
  48.  
  49. class Subtract extends CountingStrategy {
  50. public function getResult() {
  51. return $this->a - $this->b;
  52. }
  53. }
  54.  
  55. ?>


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 widzę trzeci przypadek, że jest sobie coś w stylu:

  1. interface RandomizerInterface {
  2. public function generate();
  3. }
  4.  
  5. class NormalRand implements RandomizerInterface {
  6.  
  7. public function generate() {
  8. return rand();
  9. }
  10.  
  11. }
  12.  
  13. class MtlRand implements RandomizerInterface {
  14.  
  15. public function generate() {
  16. return mt_rand();
  17. }
  18.  
  19. }


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ą, w związku z tym wystarczy:
  1. class MtlRand {
  2.  
  3. public function generate() {
  4. return mt_rand();
  5. }
  6.  
  7. }


bez zbędnych interfejsów. I widzę swojego rodzaju odbicie przypadku w przytoczonym kodzie. O to mi chodziło.

No, a teraz zmykam na sylwestra.

Do siego.
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: 4.10.2025 - 15:39