Почему унарный плюс в PHP не меняет знак числа
Узнаем, почему унарный оператор + в PHP преобразует тип, но не меняет знак числа, а унарный - выполняет и преобразование, и инвертирование знака.
Почему в PHP унарная операция от плюса к минусу работает, а обратно нет? Меня сложно чем‑то удивить, но это поведение меня озадачило. В PHP 8.3 при выполнении кода:
$a = 100;
= 100
a;
= -100
b;
= -100
Унарный плюс не изменяет знак отрицательного числа. В PHP же нет унарных операций? А тут будто бы она есть, но только в одну сторону… Как это работает и почему?
В PHP унарная операция + на самом деле не предназначена для изменения знака числа, а скорее для явного преобразования значения в числовой тип. Унарный оператор - как раз выполняет изменение знака. Такое поведение является частью спецификации языка и связано с тем, как PHP обрабатывает числовые преобразования.
Содержание
- Базовое объяснение поведения унарных операторов
- Технические детали реализации
- Сравнение с другими языками программирования
- Практические примеры использования
- Почему так было сделано?
- Как получить положительное число из отрицательного
- Заключение
Базовое объяснение поведения унарных операторов
Унарный оператор + в PHP выполняет только преобразование значения в числовой тип, но не изменяет его знак. Унарный оператор - выполняет две операции: преобразование в числовой тип и инвертирование знака.
$a = 100; // = 100 (целое число)
$b = -$a; // = -100 (преобразование в число + инвертирование знака)
$c = +$b; // = -100 (только преобразование в число, знак остается)
Это объясняется тем, что согласно документации PHP, унарный плюс предназначен для явного приведения к числовому типу, а унарный минус - для отрицания значения.
Технические детали реализации
Как PHP обрабатывает унарные операторы
Согласно исследованиям, унарный оператор + эквивалентен вызову Number() конструктора как функции, в то время как унарный оператор - сначала преобразует операнд в число, а затем инвертирует его знак.
// Внутренняя обработка PHP
+$b; // эквивалентно Number($b) - просто преобразование типа
-$b; // эквивалентно -(Number($b)) - преобразование + инвертирование
Типы данных и преобразования
При использовании унарных операторов PHP выполняет автоматическое приведение типов:
$str = "123";
$num = 456;
+$str; // = 123 (строка преобразуется в число)
-$str; // = -123 (строка преобразуется в число и инвертируется)
+$num; // = 456 (число остается без изменений)
-$num; // = -456 (число инвертируется)
Сравнение с другими языками программирования
Сходства и различия
| Язык | Унарный + | Унарный - | Примечания |
|---|---|---|---|
| PHP | Только преобразование типа | Преобразование + инвертирование | Встроенное поведение |
| JavaScript | Только преобразование типа | Преобразование + инвертирование | Похожее поведение |
| Python | Преобразование в число | Преобразование + инвертирование | Аналогично |
| C/C++ | Преобразование в int | Преобразование + инвертирование | Работает с целыми числами |
| Java | Преобразование в int | Преобразование + инвертирование | Аналогично C/C++ |
Как видно из таблицы, большинство языков программирования придерживаются схожей семантики: унарный + предназначен для явного приведения к числовому типу, а унарный - - для инвертирования знака.
Практические примеры использования
Преобразование строк в числа
Унарный + часто используется для быстрого преобразования строк в числа:
$numericString = "42";
$number = +$numericString; // = 42
// Эквивалентно:
$number = (int)$numericString; // или (float) для дробных чисел
Динамические математические операции
Унарные операторы полезны в динамических вычислениях, как показано в примере из StackOverflow:
$variable = 1;
$modifier = ($variable == 1) ? -1 : 1;
$numberOne = 10;
$numberTwo = 10;
$result = $numberOne + ($numberTwo * $modifier);
Работа с отрицательными нулями
Интересный случай описан в баг-репорте PHP:
$negativeZero = -0.0;
$positiveZero = +$negativeZero; // produces positive zero
Почему так было сделано?
Дизайн-решения PHP
Такое поведение унарных операторов было сделано по нескольким причинам:
- Ясность намерений: Унарный
+явно указывает на необходимость преобразования в число, а не на изменение знака. - Соответствие стандартам: Такое поведение соответствует стандартам ECMAScript и другим языкам программирования.
- Предсказуемость: Разделение операций преобразования типа и математического инвертирования делает код более предсказуемым.
- Производительность: Отдельные операции позволяют PHP выполнять оптимизацию преобразований типов.
Исторический контекст
В ранних версиях PHP не было строгой типизации, и унарные операторы предоставляли простой способ явно указать необходимость работы с числами.
Как получить положительное число из отрицательного
Если вам нужно превратить отрицательное число в положительное, используйте следующие подходы:
Использование математических функций
$negativeNumber = -100;
$positiveNumber = abs($negativeNumber); // = 100
Умножение на -1
$negativeNumber = -100;
$positiveNumber = -$negativeNumber; // = 100 (двойное инвертирование)
Условный оператор
$number = -100;
$positive = $number < 0 ? -$number : $number; // = 100
Bitwise операции (для целых чисел)
$negativeNumber = -100;
$positiveNumber = $negativeNumber & 0xFFFFFFFF; // для 32-битных чисел
Заключение
- Унарный
+в PHP предназначен только для преобразования значения в числовой тип, а не для изменения знака. - Унарный
-выполняет две операции: преобразование в число и инвертирование знака, что делает его “двусторонним” оператором изменения знака. - Такое поведение вполне осознанное и документированное, а не ошибка или особенность реализации.
- Для получения положительного числа из отрицательного следует использовать
abs(), умножение на -1 или другие математические операции. - Такое разделение операций сделано преднамеренно для ясности кода и соответствия стандартам программирования.
Понимание этого поведения помогает писать более предсказуемый и понятный код, особенно при работе с динамическими вычислениями и преобразованием типов.
Источники
- PHP: Operators - Manual
- Unary Operators in PHP - Tutorial
- What’s the significant use of unary plus and minus operators? - StackOverflow
- Store plus and minus in a variable PHP - StackOverflow
- PHP :: Bug #70804 :: Unary add on negative zero produces positive zero
- Unary operation - Wikipedia
- 17.2: Unary Positive and Negative Operators - Engineering LibreTexts