PHP
BC Math (binär kalkylator)
Sök…
Introduktion
Den binära kalkylatorn kan användas för att beräkna med siffror av valfri storlek och precision upp till 2147483647-1 decimaler, i strängformat. Binary Calculator är mer exakt än floatberäkningen av PHP.
Syntax
- string bcadd (sträng $ left_operand, string $ right_operand [, int $ skala = 0])
- int bccomp (string $ left_operand, string $ right_operand [, int $ skala = 0])
- sträng bcdiv (string $ left_operand, string $ right_operand [, int $ skala = 0])
- string bcmod (sträng $ left_operand, string $ modulus)
- sträng bcmul (string $ left_operand, string $ right_operand [, int $ skala = 0])
- sträng bcpowmod (string $ left_operand, string $ right_operand, string $ modulus [, int $ skala = 0])
- bool bcscale (int $ skala)
- sträng bcsqrt (sträng $ operand [, int $ skala = 0])
- string bcsub (sträng $ left_operand, string $ right_operand [, int $ skala = 0])
parametrar
bcadd | Lägg till två godtyckliga precisionsnummer. |
---|---|
left_operand | Vänster operand, som en sträng. |
right_operand | Höger operand, som en sträng. |
scale | En valfri parameter för att ställa in antalet siffror efter decimalplatsen i resultatet. |
bccomp | Jämför två godtyckliga precisionsnummer. |
left_operand | Vänster operand, som en sträng. |
right_operand | Höger operand, som en sträng. |
scale | En valfri parameter för att ställa in antalet siffror efter den decimal som ska användas i jämförelsen. |
bcdiv | Dela upp två godtyckliga precisionsnummer. |
left_operand | Vänster operand, som en sträng. |
right_operand | Höger operand, som en sträng. |
scale | En valfri parameter för att ställa in antalet siffror efter decimalplatsen i resultatet. |
bcmod | Få modul av ett godtyckligt precisionsnummer. |
left_operand | Vänster operand, som en sträng. |
modulus | Modulen, som en sträng. |
bcmul | Multiplicera två godtyckliga precisionsnummer. |
left_operand | Vänster operand, som en sträng. |
right_operand | Höger operand, som en sträng. |
scale | En valfri parameter för att ställa in antalet siffror efter decimalplatsen i resultatet. |
bcpow | Höj ett godtyckligt precisionsnummer till ett annat. |
left_operand | Vänster operand, som en sträng. |
right_operand | Höger operand, som en sträng. |
scale | En valfri parameter för att ställa in antalet siffror efter decimalplatsen i resultatet. |
bcpowmod | Höj ett godtyckligt precisionsnummer till ett annat, minskat med en specificerad modul. |
left_operand | Vänster operand, som en sträng. |
right_operand | Höger operand, som en sträng. |
modulus | Modulen, som en sträng. |
scale | En valfri parameter för att ställa in antalet siffror efter decimalplatsen i resultatet. |
bcscale | Ställ in standardskalaparameter för alla bc-matematikfunktioner. |
scale | Skalafaktorn. |
bcsqrt | Få kvadratroten av ett godtyckligt precisionsnummer. |
operand | Operanden, som en sträng. |
scale | En valfri parameter för att ställa in antalet siffror efter decimalplatsen i resultatet. |
bcsub | Dra ett godtyckligt precisionsnummer från ett annat. |
left_operand | Vänster operand, som en sträng. |
right_operand | Höger operand, som en sträng. |
scale | En valfri parameter för att ställa in antalet siffror efter decimalplatsen i resultatet. |
Anmärkningar
För alla BC funktioner, om scale
parametern inte är inställd, det standard 0, vilket kommer att göra all verksamhet heltal verksamheten.
Jämförelse mellan BCMath och float aritmetiska operationer
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"
Använda bcmath för att läsa / skriva ett binärt långt 32-bitarssystem
På 32-bitarssystem kan heltal som är större än 0x7FFFFFFF
inte lagras primitivt, medan heltal mellan 0x0000000080000000
och 0x7FFFFFFFFFFFFFFF
kan lagras primitivt på 64-bitarssystem men inte 32-bitarssystem ( signed long long
). Men eftersom 64-bitarssystem och många andra språk stöder lagring av signed long long
heltal är det ibland nödvändigt att lagra detta heltal med exakt värde. Det finns flera sätt att göra det, till exempel att skapa en matris med två siffror, eller konvertera heltalet till dess decimalt läsbara form. Detta har flera fördelar, såsom bekvämligheten med att presentera för användaren, och förmågan att manipulera det med bcmath direkt.
pack
/ unpack
metoderna kan användas för att konvertera mellan binära byte och decimalform av siffrorna (båda av string
, men en är binär och en är ASCII), men de kommer alltid att försöka kasta ASCII-strängen till en 32-bitars int på 32-bitars system. Följande kod innehåller ett alternativ:
/** 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;
}