Числа с плавающей запятой (также известные как «плавающие», «двойные» или «действительные числа») могут быть указаны с использованием любого из следующих синтаксисов:
<?php
$a = 1.234;
$b = 1.2e3;
$c = 7E-10;
$d = 1_234.567; // as of PHP 7.4.0
?>
Формально начиная с PHP 7.4.0 (ранее символы подчеркивания не допускались):
ЛЧИСЛО [0-9]+(_[0-9]+)*
DNUM ([0-9]*(_[0-9]+)*[\.]{LNUM}) | ({LNUM}[\.][0-9]*(_[0-9]+)*)
EXPONENT_DNUM (({LNUM} | {DNUM}) [eE][+-]? {LNUM})
Размер числа с плавающей запятой зависит от платформы, хотя обычное значение составляет примерно 1,8e308 с точностью примерно до 14 десятичных знаков (64-битный формат IEEE).
Точность с плавающей запятой
Числа с плавающей запятой имеют ограниченную точность. Хотя это зависит от системы, PHP обычно использует формат двойной точности IEEE 754, который дает максимальную относительную ошибку из-за округления порядка 1.11e-16. Неэлементарные арифметические операции могут давать большие ошибки, и, конечно, при объединении нескольких операций необходимо учитывать распространение ошибки.
Кроме того, рациональные числа, которые точно представляются как числа с плавающей запятой в базе 10, такие как 0.1
или 0.7
, не имеют точного представления в виде чисел с плавающей запятой в базе 2, которая используется внутри, независимо от размера мантиссы. Следовательно, их нельзя преобразовать во внутренние двоичные аналоги без небольшой потери точности. Это может привести к запутанным результатам: например, floor((0.1+0.7)*10)
обычно будет возвращаться 7
вместо ожидаемого 8
, так как внутреннее представление будет примерно таким 7.9999999999999991118...
.
Поэтому никогда не доверяйте результаты чисел с плавающей запятой до последней цифры и не сравнивайте числа с плавающей запятой напрямую на равенство. Если необходима более высокая точность, доступны математические функции произвольной точности и функции gmp .
Преобразование в число с плавающей запятой
Из строк
Если строка является числовой или ведущей числовой, то она преобразуется в соответствующее значение с плавающей запятой, в противном случае она преобразуется в ноль ( 0
).
Из других типов
Для значений других типов преобразование выполняется путем преобразования значения сначала в int , а затем в float . Дополнительную информацию см. в разделе Преобразование в целое число .
Примечание :
Поскольку некоторые типы имеют неопределенное поведение при преобразовании в int , то же самое происходит и при преобразовании в float .
Сравнение поплавков
Как отмечалось в предупреждении выше, проверка значений с плавающей запятой на равенство проблематична из-за того, как они представлены внутри. Однако существуют способы сравнения значений с плавающей запятой, позволяющие обойти эти ограничения.
Чтобы проверить значения с плавающей запятой на равенство, используется верхняя граница относительной ошибки из-за округления. Это значение известно как машинный эпсилон или единица округления и представляет собой наименьшую допустимую разницу в вычислениях.
$a и $b равны 5 цифрам точности.
<?php
$a = 1.23456789;
$b = 1.23456780;
$epsilon = 0.00001;
if(abs($a-$b) < $epsilon) {
echo "true";
}
?>
NaN
Некоторые числовые операции могут привести к значению, представленному константой NAN
. Этот результат представляет собой неопределенное или непредставимое значение в вычислениях с плавающей запятой. Любые свободные или строгие сравнения этого значения с любым другим значением, включая само себя, но кроме true
, будут иметь результат false
.
Поскольку NAN
представляет любое количество различных значений, NAN
его не следует сравнивать с другими значениями, включая себя, и вместо этого следует проверять на использование is_nan() .
0 комментариев