Buscar..


Introducción

La calculadora binaria se puede utilizar para calcular con números de cualquier tamaño y precisión hasta 2147483647-1 decimales, en formato de cadena. La calculadora binaria es más precisa que el cálculo flotante de PHP.

Sintaxis

  • 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])

Parámetros

bcadd Suma dos números de precisión arbitrarios.
left_operand El operando izquierdo, como una cuerda.
right_operand El operando correcto, como una cuerda.
scale Un parámetro opcional para establecer el número de dígitos después del lugar decimal en el resultado.
bccomp Compara dos números de precisión arbitrarios.
left_operand El operando izquierdo, como una cuerda.
right_operand El operando correcto, como una cuerda.
scale Un parámetro opcional para establecer el número de dígitos después del lugar decimal que se utilizará en la comparación.
bcdiv Divide dos números de precisión arbitrarios.
left_operand El operando izquierdo, como una cuerda.
right_operand El operando correcto, como una cuerda.
scale Un parámetro opcional para establecer el número de dígitos después del lugar decimal en el resultado.
bcmod Obtener el módulo de un número de precisión arbitrario.
left_operand El operando izquierdo, como una cuerda.
modulus El módulo, como una cuerda.
bcmul Multiplica dos números de precisión arbitrarios.
left_operand El operando izquierdo, como una cuerda.
right_operand El operando correcto, como una cuerda.
scale Un parámetro opcional para establecer el número de dígitos después del lugar decimal en el resultado.
bcpow Elevar un número de precisión arbitrario a otro.
left_operand El operando izquierdo, como una cuerda.
right_operand El operando correcto, como una cuerda.
scale Un parámetro opcional para establecer el número de dígitos después del lugar decimal en el resultado.
bcpowmod Elevar un número de precisión arbitrario a otro, reducido por un módulo específico.
left_operand El operando izquierdo, como una cuerda.
right_operand El operando correcto, como una cuerda.
modulus El módulo, como una cuerda.
scale Un parámetro opcional para establecer el número de dígitos después del lugar decimal en el resultado.
Escala Establecer el parámetro de escala predeterminado para todas las funciones matemáticas bc.
scale El factor de escala.
bcsqrt Obtener la raíz cuadrada de un número de precisión arbitraria.
operand El operando, como una cuerda.
scale Un parámetro opcional para establecer el número de dígitos después del lugar decimal en el resultado.
bcsub Resta un número de precisión arbitrario de otro.
left_operand El operando izquierdo, como una cuerda.
right_operand El operando correcto, como una cuerda.
scale Un parámetro opcional para establecer el número de dígitos después del lugar decimal en el resultado.

Observaciones

Para todas las funciones de BC, si el parámetro de scale no está establecido, el valor predeterminado es 0, lo que hará que todas las operaciones sean operaciones con enteros.

Comparación entre BCMath y operaciones aritméticas flotantes

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"

Uso de bcmath para leer / escribir un binario largo en un sistema de 32 bits

En los sistemas de 32 bits, los enteros mayores que 0x7FFFFFFF no pueden almacenarse primitivamente, mientras que los enteros entre 0x0000000080000000 y 0x7FFFFFFFFFFFFFFF pueden almacenarse primitivamente en sistemas de 64 bits pero no en sistemas de 32 bits ( signed long long ). Sin embargo, dado que los sistemas de 64 bits y muchos otros lenguajes admiten el almacenamiento de enteros signed long long , a veces es necesario almacenar este rango de enteros en el valor exacto. Hay varias formas de hacerlo, como crear una matriz con dos números o convertir el número entero en su forma decimal legible para el hombre. Esto tiene varias ventajas, como la conveniencia de presentar al usuario y la capacidad de manipularlo directamente con bcmath.

Los métodos de pack / unpack se pueden usar para convertir entre bytes binarios y la forma decimal de los números (ambos de tipo string , pero uno es binario y el otro es ASCII), pero siempre intentarán convertir la cadena ASCII en un formato de 32 bits. int en sistemas de 32 bits. El siguiente fragmento de código proporciona una alternativa:

/** 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
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow