Задать вопрос
@rinaz22

Почему PHP считает int числа после математических операций как float?

Всем привет! Сегодня случайно заметил странный аномалий. По крайней мере мне показалось это именно аномалией.
Обычная форму расчета по проценту:
$sum = 400;
$all = $sum * (55 / 100);
var_dump($all); // На выходе float(220)

На выходе получаю просто 220, без запятых и прочего. Даже не 220.000000000001, а просто 220. Но если вывести через var_dump, то показывает как float, а не int.
Из-за этого у меня сломалось одно условие проверки больше-меньше.
Пробовал переменную $all перевести в string "{$all}", так условие заработало правильно, но так неправильно, поэтому решил поставить всю мат. операцию внутрь round.
После round все заработало как надо, но вот этот момент меня все же заинтересовал. Почему так произошло? С другими числами вроде такого не замечал, но именно с такими вводными выходит такая странность.
  • Вопрос задан
  • 71 просмотр
Подписаться 1 Простой Комментировать
Решения вопроса 3
ThunderCat
@ThunderCat Куратор тега PHP
{PHP, MySql, HTML, JS, CSS} developer
Так как в выражении одним из операндов присутствует деление, результатом которого будет число с десятичной частью, естественно все дальнейшие действия будут переводить операнды в совместимый формат - с плавающей запятой. Читать про неявные преобразования в языках со слабой типизацией.
Ответ написан
Комментировать
@dim5x
ЗИ, ИБ. Помогли? Поблагодарите. Отметьте ответом.
Поскольку 55 / 100 возвращает float, результат тоже будет float.

Если нужно целое число, можно использовать intval()
Ответ написан
Комментировать
Vamp
@Vamp
Все потому, что в операции деления у вас получается float, так как операнды не поделились друг на друга без остатка. Умножение int на float в дальнейшем тоже приводится к умножению float на float.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
@Vitsliputsli
Почему PHP считает int числа после математических операций как float?

Потому что именно такое поведение описано в документации. Вообще, чтение документации отвечает на большинство вопросов. Очень рекомендую всегда начинать с нее.
Ответ написан
Комментировать
Все коллеги, ответившие выше, правы. float заразен. Всё, чего он касается в математических выражениях, превращается во float.

Я лишь хотел посоветовать эдакий костыльный подход, который позволит вам не так сильно напрягаться, вспоминая, как же эти динамические языки приводят одно к другому.

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

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

Попробуем использовать хотя бы то, что нам дали. Для этого будем придерживаться простого правила:

все вычисления всегда выносить в отдельные функции, а эти функции всегда типизировать по-максимуму.

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

<?php

$sum = 400;

// Было
$all = $sum * (55 / 100);
var_dump($all); // На выходе float(220.00000000000003)

// Стало
$all2 = calculateAll($sum);
var_dump($all2); // На выходе int(220)

function calculateAll(int $sum): int
{
    return $sum * (55 / 100);
}


Вывод
float(220.00000000000003)
PHP Deprecated:  Implicit conversion from float 220.00000000000003 to int loses precision in /Users/vitiok78/Downloads/float.php on line 12

Deprecated: Implicit conversion from float 220.00000000000003 to int loses precision in /Users/vitiok78/Downloads/float.php on line 12
int(220)
 
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы