W3docs

Числа в PHP: Полное руководство

Узнайте, как PHP работает с целыми числами и числами с плавающей точкой, арифметикой, делением, точностью float, математическими функциями и форматированием чисел.

Числа лежат в основе почти каждой PHP-программы — подсчёт элементов, вычисление цен, измерение размеров. В этой главе рассматриваются два числовых типа, которые предлагает PHP, способы записи чисел в различных нотациях, арифметические и математические функции, ловушка точности float, с которой сталкивается каждый разработчик, а также безопасное форматирование и валидация чисел.

Понимание числовых типов данных в PHP

В PHP есть два числовых типа данных:

  • int (целое число) — целое число без дробной части, например 42 или -7.
  • float (число с плавающей точкой, также называемое double) — число с дробной частью, например 3.14 или -0.5.

PHP — слабо типизированный язык, поэтому объявлять тип не нужно. PHP автоматически выбирает int или float на основе написанного вами литерала и выполняемых операций. Проверить тип во время выполнения можно с помощью gettype() или var_dump().

Размер целого числа зависит от платформы. На 64-битной системе (что сегодня является стандартом) целое число находится в диапазоне от -9 223 372 036 854 775 808 до 9 223 372 036 854 775 807; на 32-битной системе диапазон составляет от -2 147 483 648 до 2 147 483 647. Точное ограничение доступно в виде константы PHP_INT_MAX. Когда вычисление превышает его, PHP молча преобразует результат в float, а не переполняется — поэтому очень большие целые числа могут потерять точность.

Запись числовых литералов

Вы не ограничены обычной десятичной нотацией. PHP понимает несколько систем счисления, а также символы подчёркивания для удобочитаемости:

<?php
$dec = 42;        // decimal integer
$float = 3.14;    // floating-point
$hex = 0x1A;      // hexadecimal, equals 26
$oct = 0o17;      // octal (PHP 8.1+ "0o" prefix), equals 15
$bin = 0b101;     // binary, equals 5
$big = 1_000_000; // underscores are ignored (PHP 7.4+), equals 1000000

echo $hex, "\n";  // 26
echo $oct, "\n";  // 15
echo $bin, "\n";  // 5
echo $big, "\n";  // 1000000

var_dump($dec);   // int(42)
var_dump($float); // float(3.14)
?>

Символы подчёркивания носят исключительно косметический характер — PHP игнорирует их — но они делают длинные числа вроде 1_000_000 гораздо удобнее для чтения. Смотрите главу Типы данных PHP, чтобы узнать, как они сочетаются со строками, булевыми значениями и массивами.

Арифметические операции в PHP

PHP поддерживает стандартные арифметические операторы: сложение (+), вычитание (-), умножение (*), деление (/), остаток от деления (%) и возведение в степень (**). Полный набор описан в разделе Операторы PHP. Вот каждая из основных операций в действии:

<?php
$num1 = 10;
$num2 = 5;

// Addition
$result = $num1 + $num2;
echo "\$num1 + \$num2 = ";
echo $result; // 15

// Subtraction
$result = $num1 - $num2;
echo "\n\$num1 - \$num2 = ";
echo $result; // 5

// Multiplication
$result = $num1 * $num2;
echo "\n\$num1 * \$num2 = ";
echo $result; // 50

// Division
$result = $num1 / $num2;
echo "\n\$num1 / \$num2 = ";
echo $result; // 2

// Modulus
$result = $num1 % $num2;
echo "\n\$num1 % \$num2 = ";
echo $result; // 0
?>

Деление, целочисленное деление и остаток от деления

Деление в PHP имеет особенность, которую стоит знать. Оператор / возвращает float, когда результат не является целым числом, и int, когда операнды делятся нацело. Для результата, который всегда является целым числом, используйте intdiv(). Для получения остатка % работает с целыми числами, а fmod() — с числами с плавающей точкой:

<?php
var_dump(10 / 4);        // float(2.5)  — not evenly divisible
var_dump(10 / 5);        // int(2)      — evenly divisible
var_dump(intdiv(10, 4)); // int(2)      — integer division, remainder dropped
var_dump(10 % 4);        // int(2)      — modulus (remainder)
var_dump(fmod(10.5, 3)); // float(1.5)  — floating-point remainder
?>

Деление на ноль в PHP 8 и выше вызывает DivisionByZeroError, поэтому проверяйте делитель перед делением, если он может быть равен 0.

Точность чисел с плавающей точкой

Числа с плавающей точкой не могут представить каждое десятичное значение точно, поскольку хранятся в двоичном формате. Это приводит к классической неожиданности:

<?php
var_dump(0.1 + 0.2 === 0.3); // bool(false) — not exactly equal!

// Compare floats with a small tolerance instead:
$epsilon = 1e-9;
var_dump(abs((0.1 + 0.2) - 0.3) < $epsilon); // bool(true)
?>

0.1 + 0.2 на самом деле равно 0.30000000000000004, поэтому строгое сравнение === не выполняется, даже если echo округляет результат до 0.3 при выводе. Главное правило: никогда не сравнивайте числа с плавающей точкой с помощью == или === — проверяйте, что их разность меньше небольшого допуска (эпсилон). Для работы с деньгами и другими точными десятичными значениями храните значения в виде целых центов или используйте расширения BCMath / GMP.

Расширенные математические функции в PHP

Помимо операторов, PHP поставляется с богатым набором встроенных математических функций. Наиболее часто используемые из них:

  • abs() — абсолютное (неотрицательное) значение числа
  • ceil() — округляет вверх до ближайшего целого числа
  • floor() — округляет вниз до ближайшего целого числа
  • round() — округляет до ближайшего целого числа или до заданного количества десятичных знаков
  • sqrt() — квадратный корень числа
  • pow() — возводит число в степень (то же самое, что оператор **)
  • max() / min() — наибольшее / наименьшее из переданных значений
  • rand() / random_int() — случайное число (random_int() является криптографически безопасным)

Полный список находится в справочнике по математике PHP. Вот несколько функций в действии:

<?php
$num1 = -10;
$num2 = 2.7;

// Absolute value
$result = abs($num1);
echo "abs(\$num1) = ";
echo $result  . "\n"; // 10

// Round up
$result = ceil($num2);
echo "ceil(\$num2) = ";
echo $result . "\n"; // 3

// Round down
$result = floor($num2);
echo "floor(\$num2) = ";
echo $result . "\n"; // 2

// Square root
$result = sqrt(9);
echo "sqrt(9) = ";
echo $result . "\n";  // 3

// Raise to power
$result = pow(2, 3);
echo "pow(2, 3) = ";
echo $result; // 8
?>

Форматирование чисел для отображения

Необработанные числа редко хорошо выглядят на странице. Функция number_format() добавляет разделители тысяч и фиксирует количество десятичных знаков, а round() управляет точностью в вычислениях:

<?php
echo number_format(1234567.891, 2), "\n";          // 1,234,567.89
echo number_format(1234567.891, 2, '.', ' '), "\n"; // 1 234 567.89 (custom separators)
echo round(3.14159, 2), "\n";                       // 3.14
?>

Второй и последующие аргументы функции number_format() позволяют задать количество десятичных знаков и выбрать разделители для дробной и целой частей — удобно для вывода в формате, специфичном для локали.

Проверка и преобразование числовых значений

Когда данные поступают из форм, URL или файлов, они представлены в виде текста. Проверяйте их перед выполнением арифметических операций. Функции is_int() и is_float() проверяют фактический тип, а is_numeric() проверяет, выглядит ли строка как число. Для преобразования используйте приведение типа (int) / (float) или функцию floatval():

<?php
var_dump(is_int(42));          // bool(true)
var_dump(is_float(3.14));      // bool(true)
var_dump(is_numeric("123"));   // bool(true)  — numeric string
var_dump(is_numeric("12abc")); // bool(false) — not numeric

echo (int) "42px", "\n";       // 42  — leading digits are kept, the rest dropped
echo PHP_INT_MAX, "\n";        // 9223372036854775807 on a 64-bit system
?>

Связанные функции проверки типов имеют свои собственные главы: is_int() и is_float().

Заключение

В заключение следует отметить, что числа играют важнейшую роль в программировании на PHP, и важно хорошо понимать, как с ними работать. Независимо от того, выполняете ли вы базовые арифметические операции или расширенные математические функции, PHP предоставляет разнообразные инструменты для решения любых задач. Получив знания из этой статьи, вы теперь готовы справиться с любой задачей, связанной с числами, в ваших PHP-проектах.

Практика

Практика
Какие из следующих утверждений верны в отношении чисел в PHP?
Какие из следующих утверждений верны в отношении чисел в PHP?
Was this page helpful?