Szukaj…


Wprowadzenie

Kalkulator binarny może być używany do obliczania liczb o dowolnej wielkości i dokładności do 2147483647-1 miejsc po przecinku, w formacie ciągu. Kalkulator binarny jest bardziej precyzyjny niż obliczenia zmiennoprzecinkowe PHP.

Składnia

  • ciąg bcadd (ciąg $ lewy_operand, ciąg $ prawy_operand [, int $ skala = 0])
  • int bccomp (ciąg $ lewy_operand, ciąg $ prawy_operand [, int $ skala = 0])
  • ciąg bcdiv (ciąg $ lewy_operand, ciąg $ prawy_operand [, int $ skala = 0])
  • string bcmod (string $ left_operand, string $ moduł)
  • string bcmul (string $ lewy_operand, ciąg $ prawy_operand [, int $ skala = 0])
  • ciąg bcpowmod (ciąg $ lewy_operand, ciąg $ prawy_operand, ciąg $ moduł [, int $ skala = 0])
  • bool bcscale (skala int $)
  • string bcsqrt (string $ operand [, int $ scale = 0])
  • string bcsub (string $ left_operand, string $ right_operand [, int $ scale = 0])

Parametry

bcadd Dodaj dwie dowolne liczby precyzji.
left_operand Lewy operand, jako ciąg.
right_operand Właściwy operand jako ciąg.
scale Opcjonalny parametr do ustawiania liczby cyfr po przecinku w wyniku.
bccomp Porównaj dwie dowolne liczby precyzji.
left_operand Lewy operand, jako ciąg.
right_operand Właściwy operand jako ciąg.
scale Opcjonalny parametr do ustawiania liczby cyfr po przecinku, która będzie używana w porównaniu.
bcdiv Podziel dwie dowolne liczby precyzji.
left_operand Lewy operand, jako ciąg.
right_operand Właściwy operand jako ciąg.
scale Opcjonalny parametr do ustawiania liczby cyfr po przecinku w wyniku.
bcmod Uzyskaj moduł o dowolnej liczbie dokładności.
left_operand Lewy operand, jako ciąg.
modulus Moduł jako ciąg.
bcmul Pomnóż dwie dowolne liczby precyzji.
left_operand Lewy operand, jako ciąg.
right_operand Właściwy operand jako ciąg.
scale Opcjonalny parametr do ustawiania liczby cyfr po przecinku w wyniku.
bcpow Podnieś dowolną liczbę dokładności do innej.
left_operand Lewy operand, jako ciąg.
right_operand Właściwy operand jako ciąg.
scale Opcjonalny parametr do ustawiania liczby cyfr po przecinku w wyniku.
bcpowmod Podnieś dowolną liczbę precyzji do drugiej, zmniejszoną o określony moduł.
left_operand Lewy operand, jako ciąg.
right_operand Właściwy operand jako ciąg.
modulus Moduł jako ciąg.
scale Opcjonalny parametr do ustawiania liczby cyfr po przecinku w wyniku.
Bcscale Ustaw domyślny parametr skali dla wszystkich funkcji matematycznych bc.
scale Współczynnik skali.
bcsqrt Uzyskaj pierwiastek kwadratowy z dowolnej liczby dokładności.
operand Argument jako ciąg.
scale Opcjonalny parametr do ustawiania liczby cyfr po przecinku w wyniku.
bcsub Odejmij jeden dowolny numer precyzji od drugiego.
left_operand Lewy operand, jako ciąg.
right_operand Właściwy operand jako ciąg.
scale Opcjonalny parametr do ustawiania liczby cyfr po przecinku w wyniku.

Uwagi

Dla wszystkich funkcji BC, jeśli parametr scale nie jest ustawiony, domyślnie wynosi 0, co spowoduje, że wszystkie operacje będą liczbami całkowitymi.

Porównanie operacji arytmetycznych BCMath i 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"

Korzystanie z bcmath do odczytu / zapisu długości binarnej w systemie 32-bitowym

W systemach 32-bitowych liczby całkowite większe niż 0x7FFFFFFF nie mogą być przechowywane pierwotnie, podczas gdy liczby całkowite od 0x0000000080000000 do 0x7FFFFFFFFFFFFFFF mogą być przechowywane pierwotnie w systemach 64-bitowych, ale nie w systemach 32-bitowych ( signed long long ). Ponieważ jednak systemy 64-bitowe i wiele innych języków obsługuje przechowywanie signed long long liczb całkowitych ze znakiem, czasami konieczne jest przechowywanie tego zakresu liczb całkowitych w dokładnej wartości. Można to zrobić na kilka sposobów, na przykład tworząc tablicę z dwiema liczbami lub konwertując liczbę całkowitą do postaci dziesiętnej czytelnej dla człowieka. Ma to kilka zalet, takich jak wygoda prezentacji użytkownikowi i możliwość bezpośredniego manipulowania nim za pomocą bcmath.

Metod pack / unpack można użyć do konwersji między bajtami binarnymi a liczbami dziesiętnymi liczb (oba string , ale jeden jest dwójkowy, a drugi ASCII), ale zawsze będą próbowały rzutować ciąg ASCII na 32-bitowy int w systemach 32-bitowych. Poniższy fragment kodu stanowi alternatywę:

/** 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;
}


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow