2013-08-06 6 views
7

PHP udostępnia różne funkcje do obliczania modułu:

  1. Modulus operator %: echo ($a % $b);
  2. fmod()
  3. bcmod()
  4. gmp_mod()

Która funkcja powinna być używana, które uważane za bezpieczne i skuteczne? biorąc pod uwagę (devision przez zero problemu, że opisany tutaj: Division by zero error while using modulus i zmiennym numery

+3

Może powinieneś podać, w jaki sposób możesz oczekiwać zera? –

+0

edytuj i popraw to, zadałem to pytanie jako referencję –

+0

Akam, co powinno się zdarzyć, gdy napotkane zostanie zero jest specyficzne dla problemu/domeny. Jeśli zamierzasz stworzyć wiki opisujące, co te funkcje robią, idź do niego. –

Odpowiedz

21
  1. Tylko operatora modulo (%), a fmod rodzimych

  2. Operator moduł nie może obsługiwać numery poza 2^32 (na PHP działa architektura x86)

  3. fmod biegnie szybciej niż bcmod/gmp_mod ~ benchmark

  4. bcmod nie robi „T pracy z pływaków ~ here

uważam, że najlepiej jest użyć fmod, po prostu dlatego, że jest w zasięgu Math Functions, biegnie droga szybciej niż inne funkcje, a co najważniejsze, może obsługiwać duże cyfry i pływaków.

Jeśli nie planujesz używać liczb przekraczających limit lub pływasz, użyj %, ponieważ powinno być najszybsze.

+0

2. ... 'duże liczby ~ 34% 4294967296' zmień na' 2^32', który jest dużą liczbą całkowitą na 32-bitowym systemie operacyjnym OS –

+0

Będąc w obrębie funkcji Math Functions nie czyni funkcji lepszą ani szybszą od innych, należy zrozumieć ich implementację osądzać to. Jeśli ktoś planuje pozostać w limicie spławików, używanie% nadal nie jest bezpieczne, ale należy zachować maksymalne int, aby uzyskać bezpieczeństwo. – sanyi

+0

Operator% zachowuje się trochę dziwnie (PHP 5.4): "1.98% 1" daje 0 zamiast 0,98 – Erfan

1

Nadal można korzystać z operatora modulus i nadal może on być bezpieczny pod warunkiem, że planujesz spodziewać się zera w pewnym momencie, jak pokazano poniżej.

if ($y > 0) { 
    // Do the calculation 
} 
else { 
    // Do this instead 
} 

Za ukrycie ostrzeżeń można również użyć numeru Error Control Operator. Korzystając z operatora @, błąd jest pomijany.

Jednak z % liczbą całkowitą tylko można dostać tak duża, zanim zostanie przeliczone na pływaka, stąd wprowadzenie bcmod i fmod ale należy pamiętać, że obie mają swoje ograniczenia.

ja polecam GMP czy może spojrzeć na jednym z innych rozszerzonych funkcji matematycznych, istnieje również BCMath

Skoro wspomniałeś bezpieczne coś istnieje klasa dla tego: Eval Math

tutaj przykład dla fmod

<?php 
echo fmod('4294967296', 34); 
?> 

wyjścia 18

+0

możesz spróbować tego: 'echo (34% 4294967296)' –

+0

Odpowiedź, o ile mi wiadomo, w systemie 32-bitowym jest w rzeczywistości 0, ponieważ nie może być reprezentowany przez liczbę. Podczas pracy możesz użyć http://php.net/manual/en/function.unpack.php –

0

Zauważ, że fmod nie jest równoznaczne z tej podstawowej funkcji:

<?php 
    function modulo($a, $b) { 
    return $a - $b * floor($a/$b); 
    } 
    ?> 

ponieważ fmod() zwróci wartość z tego samego znaku jako $ a. Innymi słowy funkcja floor() nie jest poprawna, ponieważ zaokrągla w kierunku -INF zamiast w kierunku zera.

naśladować fmod ($ a, $ b) prawidłowe sposobem jest:

<?php 
    function fmod($a, $b) { 
    return $a - $b * (($b < 0) ? ceil($a/$b) : floor($a/$b))); 
    } 
    ?> 

Należy zauważyć, że obie funkcje będą rzucać dzielenie przez zero, jeśli $ b ma wartość null.

Pierwsza funkcja modulo() powyżej jest funkcją matematyczną, która jest przydatna do pracy na cyklicznych struktur (takich jak computions z kalendarza lub trignonometric funkcji:

- fmod($a, 2*PI) returns a value in [0..2*PI) if $a is positive 
    - fmod($a, 2*PI) returns a value in [-2*PI..0] if $a is negative 
    - modulo($a, 2*PI) returns a value always in [0..2*PI) independantly of the sign of $a 
2

Wszystkie funkcje są bezpieczne w użyciu dostarczyć jeden wie, co jest robi:

  1. operatora Younga: jest szybki, dokładny, ale trzeba zatrzymać się pod int max nie ma podziału przez zero problemu w ogóle w tych kategoriach

  2. ..
  3. fmod: szybka, zmiennoprzecinkowa szybkość działania nie jest już problemem w ciągu ostatnich 10 lat, ale jest trudna. Liczby zmiennoprzecinkowe mogą osiągać znacznie wyższe wartości, ale ich dokładność nie. Tak więc praca z dużymi liczbami będzie coraz częściej wprowadzać błędy zaokrąglania. Tak więc nie rozwiąże niczego, co zamiast tego operator modułu nie wprowadzi, spowoduje problemy z precyzją.

  4. bcmod i gmp_mod są podobne. Różnica polega na tym, że funkcje te wykorzystują inną implementację (moduły) arbitralnej arytmetyki precyzyjnej. Ich użycie jest inne, ale ich wyniki nie są następujące: teoretycznie wielkość liczb obsługiwanych przez te biblioteki jest ograniczona jedynie ilością wolnej pamięci, więc praktycznie wynik będzie zawsze dobry i dokładny, jednak zastosowane algorytmy są przesadzone zarówno obliczeniowo, jak iz punkt widzenia pamięci.

Powiązane problemy