PHP
BC Math (Binaire Calculator)
Zoeken…
Invoering
De binaire rekenmachine kan worden gebruikt om te berekenen met getallen van elke grootte en precisie tot 2147483647-1 decimalen, in tekenreeksformaat. De binaire calculator is nauwkeuriger dan de float-berekening van PHP.
Syntaxis
- string bcadd (string $ left_operand, string $ right_operand [, int $ scale = 0])
- int bccomp (string $ left_operand, string $ right_operand [, int $ scale = 0])
- string bcdiv (string $ left_operand, string $ right_operand [, int $ scale = 0])
- string bcmod (string $ left_operand, string $ modulus)
- string bcmul (string $ left_operand, string $ right_operand [, int $ scale = 0])
- string bcpowmod (string $ left_operand, string $ right_operand, string $ 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])
parameters
bcadd | Voeg twee willekeurige precisienummers toe. |
---|---|
left_operand | De linker operand, als een string. |
right_operand | De juiste operand, als een string. |
scale | Een optionele parameter om het aantal cijfers achter de komma in het resultaat in te stellen. |
bccomp | Vergelijk twee willekeurige precisienummers. |
left_operand | De linker operand, als een string. |
right_operand | De juiste operand, als een string. |
scale | Een optionele parameter om het aantal cijfers na de decimale positie in te stellen dat in de vergelijking wordt gebruikt. |
bcdiv | Verdeel twee willekeurige precisienummers. |
left_operand | De linker operand, als een string. |
right_operand | De juiste operand, als een string. |
scale | Een optionele parameter om het aantal cijfers achter de komma in het resultaat in te stellen. |
bcmod | Krijg modulus van een willekeurig precisienummer. |
left_operand | De linker operand, als een string. |
modulus | De modulus, als een string. |
bcmul | Vermenigvuldig twee willekeurige precisienummers. |
left_operand | De linker operand, als een string. |
right_operand | De juiste operand, als een string. |
scale | Een optionele parameter om het aantal cijfers achter de komma in het resultaat in te stellen. |
bcpow | Verhoog een willekeurig precisienummer naar een ander. |
left_operand | De linker operand, als een string. |
right_operand | De juiste operand, als een string. |
scale | Een optionele parameter om het aantal cijfers achter de komma in het resultaat in te stellen. |
bcpowmod | Verhoog een willekeurig precisienummer naar een ander, verminderd met een gespecificeerde modulus. |
left_operand | De linker operand, als een string. |
right_operand | De juiste operand, als een string. |
modulus | De modulus, als een string. |
scale | Een optionele parameter om het aantal cijfers achter de komma in het resultaat in te stellen. |
bcscale | Stel de standaard schaalparameter in voor alle BC wiskundige functies. |
scale | De schaalfactor. |
bcsqrt | Krijg de vierkantswortel van een willekeurig precisienummer. |
operand | De operand, als een string. |
scale | Een optionele parameter om het aantal cijfers achter de komma in het resultaat in te stellen. |
bcsub | Trek het ene willekeurige precisienummer af van het andere. |
left_operand | De linker operand, als een string. |
right_operand | De juiste operand, als een string. |
scale | Een optionele parameter om het aantal cijfers achter de komma in het resultaat in te stellen. |
Opmerkingen
Voor alle BC-functies, als de parameter scale
niet is ingesteld, wordt deze standaard ingesteld op 0, waardoor alle bewerkingen gehele bewerkingen worden.
Vergelijking tussen rekenkundige bewerkingen BCMath en 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"
Bcmath gebruiken om een binair getal op een 32-bits systeem te lezen / schrijven
Op 32-bit systemen kunnen gehele getallen groter dan 0x7FFFFFFF
niet primitief worden opgeslagen, terwijl gehele getallen tussen 0x0000000080000000
en 0x7FFFFFFFFFFFFFFF
primitief kunnen worden opgeslagen op 64-bit systemen maar niet op 32-bit systemen ( signed long long
). Omdat 64-bits systemen en veel andere talen het opslaan van signed long long
gehele getallen ondersteunen, is het soms noodzakelijk om dit bereik van gehele getallen in exacte waarde op te slaan. Er zijn verschillende manieren om dit te doen, zoals het maken van een array met twee getallen of het omzetten van het gehele getal in de voor de mens leesbare vorm. Dit heeft verschillende voordelen, zoals het gemak van presenteren aan de gebruiker en de mogelijkheid om het rechtstreeks met bcmath te manipuleren.
De pack
/ unpack
methoden kunnen worden gebruikt om te converteren tussen binaire bytes en de decimale vorm van de getallen (beide van het type string
, maar één is binair en één is ASCII), maar ze zullen altijd proberen de ASCII-string in een 32-bit te casten int op 32-bit systemen. Het volgende fragment biedt een alternatief:
/** 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;
}