PHP
BC Math (calculatrice binaire)
Recherche…
Introduction
La calculatrice binaire peut être utilisée pour calculer avec des nombres de toute taille et précision jusqu’à 2147483647-1 décimales, au format chaîne. La calculatrice binaire est plus précise que le calcul flottant de PHP.
Syntaxe
- string bcadd (chaîne $ left_operand, chaîne $ right_operand [, int $ scale = 0])
- int bccomp (chaîne $ left_operand, chaîne $ right_operand [, int $ scale = 0])
- chaîne bcdiv (chaîne $ left_operand, chaîne $ right_operand [, int $ scale = 0])
- chaîne bcmod (chaîne $ left_operand, chaîne $ modulus)
- string bcmul (string $ left_operand, string $ right_operand [, int $ scale = 0])
- chaîne bcpowmod (chaîne $ left_operand, chaîne $ right_operand, chaîne $ modulus [, int $ scale = 0])
- bool bcscale (int $ scale)
- string bcsqrt (string $ operand [, int $ scale = 0])
- string bcsub (string $ left_operand, string $ right_operand [, int $ scale = 0])
Paramètres
bcadd | Ajoutez deux nombres de précision arbitraires. |
---|---|
left_operand | L'opérande gauche, sous forme de chaîne. |
right_operand | Le bon opérande, sous forme de chaîne. |
scale | Un paramètre facultatif pour définir le nombre de chiffres après la décimale dans le résultat. |
bccomp | Comparez deux nombres de précision arbitraires. |
left_operand | L'opérande gauche, sous forme de chaîne. |
right_operand | Le bon opérande, sous forme de chaîne. |
scale | Un paramètre facultatif pour définir le nombre de chiffres après la décimale qui sera utilisé dans la comparaison. |
bcdiv | Diviser deux nombres de précision arbitraires. |
left_operand | L'opérande gauche, sous forme de chaîne. |
right_operand | Le bon opérande, sous forme de chaîne. |
scale | Un paramètre facultatif pour définir le nombre de chiffres après la décimale dans le résultat. |
bcmod | Récupère le module d'un nombre de précision arbitraire. |
left_operand | L'opérande gauche, sous forme de chaîne. |
modulus | Le module, sous forme de chaîne. |
bcmul | Multipliez deux nombres de précision arbitraires. |
left_operand | L'opérande gauche, sous forme de chaîne. |
right_operand | Le bon opérande, sous forme de chaîne. |
scale | Un paramètre facultatif pour définir le nombre de chiffres après la décimale dans le résultat. |
bcpow | Élever un nombre arbitraire de précision à un autre. |
left_operand | L'opérande gauche, sous forme de chaîne. |
right_operand | Le bon opérande, sous forme de chaîne. |
scale | Un paramètre facultatif pour définir le nombre de chiffres après la décimale dans le résultat. |
bcpowmod | Augmenter un nombre de précision arbitraire à un autre, réduit d'un module spécifié. |
left_operand | L'opérande gauche, sous forme de chaîne. |
right_operand | Le bon opérande, sous forme de chaîne. |
modulus | Le module, sous forme de chaîne. |
scale | Un paramètre facultatif pour définir le nombre de chiffres après la décimale dans le résultat. |
bcscale | Définit le paramètre d'échelle par défaut pour toutes les fonctions mathématiques bc. |
scale | Le facteur d'échelle. |
bcsqrt | Obtenez la racine carrée d'un nombre de précision arbitraire. |
operand | L'opérande, sous forme de chaîne. |
scale | Un paramètre facultatif pour définir le nombre de chiffres après la décimale dans le résultat. |
bcsub | Soustraire un nombre de précision arbitraire d'un autre. |
left_operand | L'opérande gauche, sous forme de chaîne. |
right_operand | Le bon opérande, sous forme de chaîne. |
scale | Un paramètre facultatif pour définir le nombre de chiffres après la décimale dans le résultat. |
Remarques
Pour toutes les fonctions BC, si le paramètre scale
n'est pas défini, sa valeur par défaut est 0, ce qui rend toutes les opérations sur les entiers.
Comparaison entre les opérations arithmétiques BCMath et float
bcadd vs float + float
var_dump('10' + '-9.99'); // float(0.0099999999999998)
var_dump(10 + -9.99); // float(0.0099999999999998)
var_dump(10.00 + -9.99); // float(0.0099999999999998)
var_dump(bcadd('10', '-9.99', 20)); // string(22) "0.01000000000000000000"
bcsub vs float-float
var_dump('10' - '9.99'); // float(0.0099999999999998)
var_dump(10 - 9.99); // float(0.0099999999999998)
var_dump(10.00 - 9.99); // float(0.0099999999999998)
var_dump(bcsub('10', '9.99', 20)); // string(22) "0.01000000000000000000"
bcmul vs int * int
var_dump('5.00' * '2.00'); // float(10)
var_dump(5.00 * 2.00); // float(10)
var_dump(bcmul('5.0', '2', 20)); // string(4) "10.0"
var_dump(bcmul('5.000', '2.00', 20)); // string(8) "10.00000"
var_dump(bcmul('5', '2', 20)); // string(2) "10"
bcmul vs float * float
var_dump('1.6767676767' * '1.6767676767'); // float(2.8115498416259)
var_dump(1.6767676767 * 1.6767676767); // float(2.8115498416259)
var_dump(bcmul('1.6767676767', '1.6767676767', 20)); // string(22) "2.81154984162591572289"
bcdiv vs float / float
var_dump('10' / '3.01'); // float(3.3222591362126)
var_dump(10 / 3.01); // float(3.3222591362126)
var_dump(10.00 / 3.01); // float(3.3222591362126)
var_dump(bcdiv('10', '3.01', 20)); // string(22) "3.32225913621262458471"
Utiliser bcmath pour lire / écrire un long binaire sur un système 32 bits
Sur les systèmes 32 bits, les entiers supérieurs à 0x7FFFFFFF
ne peuvent pas être stockés primitivement, tandis que les entiers compris entre 0x0000000080000000
et 0x7FFFFFFFFFFFFFFF
peuvent être stockés primitivement sur les systèmes 64 bits, mais pas sur les systèmes 32 bits ( signed long long
). Cependant, les systèmes 64 bits et de nombreux autres langages prenant en charge le stockage d'entiers signed long long
, il est parfois nécessaire de stocker cette plage d'entiers en valeur exacte. Il existe plusieurs manières de le faire, telles que la création d’un tableau à deux chiffres ou la conversion du nombre entier sous sa forme décimale. Cela présente plusieurs avantages, tels que la facilité de présentation à l'utilisateur et la possibilité de le manipuler directement avec bcmath.
Les méthodes pack
/ unpack
peuvent être utilisées pour convertir entre les octets binaires et la forme décimale des nombres (tous deux de type string
, mais l'un est binaire et l'autre ASCII), mais ils essaieront toujours de convertir la chaîne ASCII en 32 bits. int sur les systèmes 32 bits. L'extrait suivant fournit une alternative:
/** Use pack("J") or pack("p") for 64-bit systems */
function writeLong(string $ascii) : string {
if(bccomp($ascii, "0") === -1) { // if $ascii < 0
// 18446744073709551616 is equal to (1 << 64)
// remember to add the quotes, or the number will be parsed as a float literal
$ascii = bcadd($ascii, "18446744073709551616");
}
// "n" is big-endian 16-bit unsigned short. Use "v" for small-endian.
return pack("n", bcmod(bcdiv($ascii, "281474976710656"), "65536")) .
pack("n", bcmod(bcdiv($ascii, "4294967296"), "65536")) .
pack("n", bcdiv($ascii, "65536"), "65536")) .
pack("n", bcmod($ascii, "65536"));
}
function readLong(string $binary) : string {
$result = "0";
$result = bcadd($result, unpack("n", substr($binary, 0, 2)));
$result = bcmul($result, "65536");
$result = bcadd($result, unpack("n", substr($binary, 2, 2)));
$result = bcmul($result, "65536");
$result = bcadd($result, unpack("n", substr($binary, 4, 2)));
$result = bcmul($result, "65536");
$result = bcadd($result, unpack("n", substr($binary, 6, 2)));
// if $binary is a signed long long
// 9223372036854775808 is equal to (1 << 63) (note that this expression actually does not work even on 64-bit systems)
if(bccomp($result, "9223372036854775808") !== -1) { // if $result >= 9223372036854775807
$result = bcsub($result, "18446744073709551616"); // $result -= (1 << 64)
}
return $result;
}