2013-08-06 19 views
7

PHP fornisce diverse funzioni per il modulo di calcolo:

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

Quale funzione deve essere utilizzato quello considerato sicuro ed efficace? considerando la (devision dal numero zero quello descritto qui: Division by zero error while using modulus e numeri galleggianti

+3

Forse dovresti indicare come ti aspetti di gestire uno zero? –

+0

si prega di modificare e migliorare, ho chiesto a questa domanda di essere utilizzato come riferimento –

+0

Akam, ciò che dovrebbe accadere quando si incontra uno zero è specifico per il problema/dominio. Se stai per creare una wiki che descriva ciò che fanno queste funzioni, fallo. –

risposta

21
  1. Solo l'operatore modulo (%), e fmod sono nativi

  2. L'operatore modulo non può gestire numeri oltre 2^32 (su PHP in esecuzione architettura x86)

  3. fmod corre più veloce di bcmod/gmp_mod ~ benchmark

  4. bcmod doesn 'T lavorare con i galleggianti ~ here

Credo che sia meglio usare fmod, semplicemente perché è all'interno Math Functions, corre modo più veloce di altre funzioni, e, soprattutto, in grado di gestire grandi numeri e carri allegorici.

Se non si prevede di utilizzare i numeri oltre il limite o float, utilizzare % come dovrebbe essere il più veloce.

+0

2. ... 'numeri grandi ~ 34% 4294967296' cambia in' 2^32' che è un numero intero grande su sistema operativo a 32 bit –

+0

Essere all'interno delle funzioni matematiche non rende una funzione migliore o più veloce di altre, si dovrebbe comprendere la loro implementazione per giudicare questo. Se si prevede di rimanere sotto il limite dei float non è ancora sicuro usare%, si dovrebbe rimanere al di sotto di max int per raggiungere la sicurezza. L'operatore – sanyi

+0

% si comporta in modo un po 'strano (PHP 5.4): "1.98% 1' risulta in 0 invece che 0.98 – Erfan

1

È ancora possibile utilizzare l'operatore modulo e può essere comunque sicuro se si prevede di prevedere uno zero in qualche punto, come mostrato di seguito.

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

Per soli nascondendo le avvertenze potrebbe anche utilizzare un Error Control Operator. Utilizzando l'operatore @, l'errore viene eliminato.

Tuttavia con % un numero intero può ottenere solo così grande prima che venga convertito in un galleggiante, quindi l'introduzione di bcmod e fmod ma si prega di notare che entrambi hanno i loro limiti.

avrei caldamente GMP o forse dare un'occhiata a una delle altre funzioni matematiche avanzate, c'è anche BCMath

Dal momento che lei ha citato qualcosa di sicuro c'è una classe per questo: Eval Math

Ecco un esempio usando fmod

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

uscite 18

+0

puoi provare questo:' echo (34% 4294967296) ' –

+0

La risposta per quanto ne so, su un sistema a 32 bit è in realtà 0 perché non può essere rappresentato da un numero. Come soluzione, potresti usare http://php.net/manual/en/function.unpack.php –

0

noti che fmod non è equivalente a questa funzione di base:

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

perché fmod() restituirà un valore con lo stesso segno da $ a. In altre parole, la funzione floor() non è corretta mentre si arrotonda verso -INF anziché verso zero.

di emulare fmod ($ a, $ b) il modo corretto è:

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

nota che entrambe le funzioni lancerà una divisione per zero se $ b è nullo.

La prima funzione modulo() di cui sopra è la funzione matematica che è utile per lavori su strutture cicliche (come computions calandra o funzioni trignonometric:

- 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

Tutte le funzioni sono sicuri da usare fornire sa cosa fare:

  1. operatore modulo: è veloce, preciso ma è necessario rimanere sotto il massimo int non v'è alcuna divisione per numero zero di sorta in questi termini

  2. ..
  3. fmod: stil veloce, la velocità di funzionamento in virgola mobile non è più un problema negli ultimi 10 anni, ma è difficile. I numeri in virgola mobile possono raggiungere valori molto più alti ma la loro precisione no. Quindi lavorare con grandi numeri introdurrà sempre più errori di arrotondamento. Quindi non risolverà nulla che l'operatore del modulo manchi invece introdurrà problemi di precisione.

  4. bcmod e gmp_mod sono simili. La differenza è che queste funzioni utilizzano diverse implementazioni (moduli) di aritmetica di precisione arbitraria. Il loro utilizzo è diverso, ma i risultati non sono: In teoria la dimensione dei numeri supportati da queste librerie è limitata solo dalla quantità di memoria libera, quindi in pratica il risultato sarà sempre buono e preciso, tuttavia gli algoritmi utilizzati sono eccessivi sia dal punto di vista computazionale che da punto di vista della memoria.