Числа в PHP: полное руководство по типам и операциям
Работа с цифровыми значениями в PHP: числовые типы и операции
Как правильно выбрать тип данных для численного значения?
В PHP числовые данные делятся на два основных типа: int (целые числа) и float (числа с плавающей точкой). Рекомендуется явно указывать ожидаемый тип с помощью строгой типизации (declare(strict_types=1);) или функций приведения. Для финансовых и точных расчётов следует применять расширение BC Math.
<?php
declare(strict_types=1);
// Целочисленное значение
$count = 5;
// Число с плавающей точкой
$price = 19.99;
// Преобразование строки в число
$value = (int) '42'; // 42
$decimal = (float) '3.14'; // 3.14
?>
Типичная ошибка: при сложении строки и числа PHP может выполнить неявное преобразование, что приводит к неожиданным результатам. Использование строгой типизации предотвращает эту проблему.
Как выполняется приведение типов для чисел?
Приведение типов возможно через операторы (int), (float), (string) или функции intval(), floatval(). Пример:
<?php
$mixed = '123.45abc';
$intVal = (int) $mixed; // 123
$floatVal = (float) $mixed; // 123.45
?>
Проблема: некорректное приведение строки, содержащей буквы, может дать ноль ((int) 'test' = 0). Рекомендуется предварительно проверять значение с помощью is_numeric().
Как избежать проблем с точностью дробных чисел?
Числа с плавающей точкой в двоичном представлении не всегда точны. Для финансовых расчётов используйте функции bcadd(), bcsub(), bcmul(), bcdiv() из расширения BC Math.
<?php
$a = '0.1';
$b = '0.2';
echo bcadd($a, $b, 2); // 0.30
// Обычное сложение
var_dump(0.1 + 0.2); // float(0.30000000000000004)
?>
Ошибка: сравнение float-значений напрямую (if (0.1 + 0.2 === 0.3)) даёт false. Решение: использовать небольшой допуск (epsilon) или работать с целыми копейками (умножать на 100).
Как форматировать числа для вывода?
Функция number_format() позволяет задать количество знаков после запятой, десятичный и тысячный разделители.
<?php
$price = 12345.6789;
echo number_format($price, 2, ',', ' '); // 12 345,68
?>
Проблема: по умолчанию number_format() использует точку в качестве десятичного разделителя и запятую для тысяч. Для локализации требуется явно передавать параметры.
Какие функции округления доступны?
PHP предлагает round(), ceil(), floor(). round() поддерживает параметр точности и режим (PHP_ROUND_HALF_UP и др.).
<?php
echo round(3.14159, 2); // 3.14
echo ceil(4.1); // 5
echo floor(4.9); // 4
?>
Типичная ошибка: округление до целого с помощью intval() отбрасывает дробную часть, а не округляет. Например intval(3.9) = 3.
Как проверять, является ли значение числом?
Функции is_int(), is_float(), is_numeric() помогают определить тип или числовую природу переменной.
<?php
$var1 = 42;
$var2 = '42.5';
var_dump(is_int($var1)); // true
var_dump(is_numeric($var2)); // true
var_dump(is_float($var2)); // false (это строка)
?>
Ошибка: is_numeric() возвращает true для строк, содержащих допустимые числовые форматы (с экспонентой, ведущими пробелами). Это может привести к ложным срабатываниям.
Расширенные примеры работы с числами
Использование целочисленного деления и остатка
Для получения целой части и остатка от деления применяются intdiv() и % или fmod() для float.
<?php
$a = 10;
$b = 3;
echo intdiv($a, $b); // 3
echo $a % $b; // 1
// Для чисел с плавающей точкой
$c = 10.5;
$d = 3.2;
echo fmod($c, $d); // 0.9
?>
3
1
0.9
Работа с очень большими числами
Обычные целые числа имеют ограничение (зависит от архитектуры). Для чисел больше PHP_INT_MAX используйте GMP или BC Math.
<?php
// GMP (требует установки расширения)
$a = gmp_init('12345678901234567890');
$b = gmp_init('98765432109876543210');
$sum = gmp_add($a, $b);
echo gmp_strval($sum);
?>
111111111011111111100
Преобразование строки с экспонентой
PHP корректно обрабатывает экспоненциальную запись при приведении к float.
<?php
$scientific = '1.5e3';
$value = (float) $scientific; // 1500.0
echo $value;
?>
1500
Использование числа как маски (битовые операции)
Целые числа можно использовать для битовых масок.
<?php
$permissions = 0b0011; // 3 в двоичной
$read = 0b0001; // 1
$write = 0b0010; // 2
if ($permissions & $read) {
echo 'Можно читать';
}
if ($permissions & $write) {
echo 'Можно писать';
}
?>
Можно читатьМожно писать
Обработка числовых строк с разными локалями
При получении данных из внешних источников десятичный разделитель может быть запятой. Функция str_replace() или NumberFormatter помогают нормализовать.
<?php
$localePrice = '1 234,56';
$normalized = str_replace([' ', ','], ['', '.'], $localePrice);
$price = (float) $normalized; // 1234.56
echo $price;
?>
1234.56
Получение случайного числа с плавающей точкой
Для генерации случайного float в заданном диапазоне можно комбинировать rand() или random_int().
<?php
$min = 0.0;
$max = 1.0;
$randomFloat = $min + ($max - $min) * (rand() / getrandmax());
echo $randomFloat;
?>
0.723456789
Использование строгой типизации для защиты от неявного преобразования
Объявление strict_types=1 заставляет функции принимать только правильные типы.
<?php
declare(strict_types=1);
function add(int $a, int $b): int {
return $a + $b;
}
echo add(5, '10'); // Fatal error: Argument 2 must be of type int, string given
?>
Fatal error: Uncaught TypeError: add(): Argument #2 ($b) must be of type int, string given