Affrontare i grandi interni in PHP a 32 bit
-
12-12-2019 - |
Domanda
Ho una classe per il calcolo del checksum di LUHN per un numero. Ci vuole un numero intero come input e restituisce true o false per indicare validità o in altro modo, oppure genera un'eccezione se viene fornito un tipo di dati inappropriato come input.
Il codice è il seguente (la fonte completa è su GitHub ):
class Luhn extends abstr\Prop implements iface\Prop
{
/**
* Test that the given data passes a Luhn check.
*
* @return bool True if the data passes the Luhn check
* @throws \InvalidArgumentException
* @see http://en.wikipedia.org/wiki/Luhn_algorithm
*/
public function isValid ()
{
$data = $this -> getData ();
$valid = false;
switch (gettype ($data))
{
case 'NULL' :
$valid = true;
break;
case 'integer' :
// Get the sequence of digits that make up the number under test
$digits = array_reverse (array_map ('intval', str_split ((string) $data)));
// Walk the array, doubling the value of every second digit
for ($i = 0, $count = count ($digits); $i < $count; $i++)
{
if ($i % 2)
{
// Double the digit
if (($digits [$i] *= 2) > 9)
{
// Handle the case where the doubled digit is over 9
$digits [$i] -= 10;
$digits [] = 1;
}
}
}
// The Luhn is valid if the sum of the digits ends in a 0
$valid = ((array_sum ($digits) % 10) === 0);
break;
default :
// An attempt was made to apply the check to an invalid data type
throw new \InvalidArgumentException (__CLASS__ . ': This property cannot be applied to data of type ' . gettype ($data));
break;
}
return ($valid);
}
}
.
Ho anche costruito un full Test dell'unità < / a> per esercitare la classe.
Soluzione
Se hai bisogno di precisione, non dovresti usare i galleggianti.
Invece, specialmente come vuoi lavorare con interi ( se capisco correttamente ), è possibile provare a lavorare con le funzioni gmp*
: GMP - GNU PRECISIONE MULTIME
Se non puoi lavorare con quell'estensione potresti ottenere alcune altre idee da
Altri suggerimenti
Se hai bisogno di precisione, non dovresti usare i galleggianti.
Invece, specialmente come vuoi lavorare con numeri interi (se ho capito correttamente) , è possibile provare a lavorare con le funzioni bc*
: BCMath Arbitrary Precision Mathematics