PHP
BC Math (бинарный калькулятор)
Поиск…
Вступление
Двоичный калькулятор может использоваться для вычисления с числами любого размера и точности до 2147483647-1 десятичных знаков в строчном формате. Бинарный калькулятор более точен, чем вычисление поплавка PHP.
Синтаксис
- string bcadd (строка $ left_operand, строка $ right_operand [, int $ scale = 0])
- int bccomp (строка $ left_operand, строка $ right_operand [, int $ scale = 0])
- string bcdiv (строка $ left_operand, строка $ right_operand [, int $ scale = 0])
- строка bcmod (строка $ left_operand, строковый $ модуль)
- string bcmul (строка $ left_operand, строка $ right_operand [, int $ scale = 0])
- string bcpowmod (строка $ left_operand, строка $ right_operand, строка $ modulus [, int $ scale = 0])
- bool bcscale (int $ scale)
- string bcsqrt (string $ operand [, int $ scale = 0])
- строка bcsub (строка $ left_operand, строка $ right_operand [, int $ scale = 0])
параметры
bcadd | Добавьте два произвольных числа точности. |
---|---|
left_operand | Левый операнд, как строка. |
right_operand | Правильный операнд, как строка. |
scale | Необязательный параметр для установки количества цифр после десятичного знака в результате. |
bccomp | Сравните два произвольных числа точности. |
left_operand | Левый операнд, как строка. |
right_operand | Правильный операнд, как строка. |
scale | Необязательный параметр для установки числа цифр после десятичного знака, которое будет использоваться при сравнении. |
bcdiv | Разделите два числа произвольной точности. |
left_operand | Левый операнд, как строка. |
right_operand | Правильный операнд, как строка. |
scale | Необязательный параметр для установки количества цифр после десятичного знака в результате. |
bcmod | Получить модуль произвольного числа точности. |
left_operand | Левый операнд, как строка. |
modulus | Модуль, как строка. |
bcmul | Умножьте два произвольных числа точности. |
left_operand | Левый операнд, как строка. |
right_operand | Правильный операнд, как строка. |
scale | Необязательный параметр для установки количества цифр после десятичного знака в результате. |
bcpow | Поднимите произвольное число точности в другое. |
left_operand | Левый операнд, как строка. |
right_operand | Правильный операнд, как строка. |
scale | Необязательный параметр для установки количества цифр после десятичного знака в результате. |
bcpowmod | Поднимите произвольное число точности в другое, уменьшенное на определенный модуль. |
left_operand | Левый операнд, как строка. |
right_operand | Правильный операнд, как строка. |
modulus | Модуль, как строка. |
scale | Необязательный параметр для установки количества цифр после десятичного знака в результате. |
bcscale | Установите параметр масштаба по умолчанию для всех математических функций bc. |
scale | Масштабный коэффициент. |
bcsqrt | Получите квадратный корень из произвольного числа точности. |
operand | Операнд, как строка. |
scale | Необязательный параметр для установки количества цифр после десятичного знака в результате. |
bcsub | Вычтите одно произвольное число точности из другого. |
left_operand | Левый операнд, как строка. |
right_operand | Правильный операнд, как строка. |
scale | Необязательный параметр для установки количества цифр после десятичного знака в результате. |
замечания
Для всех функций BC, если параметр scale
не установлен, по умолчанию он равен 0, что сделает все операции целыми операциями.
Сравнение между BCMath и арифметическими операциями 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 для чтения / записи двоичной длинной 32-битной системы
В 32-битных системах целые числа, превышающие 0x7FFFFFFF
не могут быть сохранены примитивно, тогда как целые числа от 0x0000000080000000
до 0x7FFFFFFFFFFFFFFF
могут быть сохранены примитивно на 64-битных системах, но не на 32-битных системах ( signed long long
0x7FFFFFFFFFFFFFFF
). Однако, поскольку 64-битные системы и многие другие языки поддерживают хранение signed long long
целых чисел, иногда необходимо хранить этот диапазон целых чисел в точном значении. Существует несколько способов сделать это, например, создать массив с двумя числами или преобразовать целое число в его десятичную удобочитаемую форму. Это имеет ряд преимуществ, таких как удобство представления пользователю и возможность непосредственного манипулирования им с помощью bcmath.
Методы pack
/ unpack
могут использоваться для преобразования между двоичными байтами и десятичной формой чисел (оба типа string
, но один из них двоичный, а один - ASCII), но они всегда будут пытаться преобразовать строку ASCII в 32-разрядную int на 32-битных системах. Следующий фрагмент предоставляет альтернативу:
/** 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;
}