## Числа с плавающей точкой

Числа с плавающей запятой в руководстве называются «числами с плавающей точкой», поскольку в английском языке — языке оригинала PHP-руководства — целую и дробную часть в таких числах разделяет точка, а не запятая. В других языках программирования числа с плавающей точкой называют также: float, double или real. В PHP числа с плавающей точкой записывают следующими синтаксисами:

    <?php

    $a = 1.234;
    $b = 1.2e3;
    $c = 7E-10;
    $d = 1_234.567; // Начиная с PHP 7.4.0

    ?>

Поддержка подчёркиваний в числах появилась с PHP 7.4.0:

    LNUM          [0-9]+(_[0-9]+)*
    DNUM          ({LNUM}?"."{LNUM}) | ({LNUM}"."{LNUM}?)
    EXPONENT_DNUM (({LNUM} | {DNUM}) [eE][+-]? {LNUM})

Размер числа с плавающей точкой зависит от платформы, хотя максимум обычного значения с плавающей точкой составляет примерно 1.8e308 с точностью около 14 десятичных цифр (64-битный формат стандарта IEEE).

Внимание

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

Точность чисел с плавающей точкой ограничена. Хотя точность зависит от операционной системы, PHP обычно использует формат двойной точности, который определяет стандарт IEEE 754, который даёт максимальную относительную погрешность округления порядка 1.11e-16. Неэлементарные арифметические операции иногда дают бо́льшие ошибки, и, конечно, учитывают распространение ошибок при объединении операции.

Кроме того, рациональные числа наподобие `0.1` или `0.7`, которые легко точно представить как числа с плавающей точкой по основанию 10 — в десятичной системе счисления, внутренне невозможно точно представить как числа с плавающей точкой по основанию 2 — в двоичной системе счисления, независимо от размера мантиссы. Поэтому такие числа невозможно преобразовать во внутреннюю двоичную форму без небольшой потери точности. Иногда это даёт противоречивые результаты: например, округление `floor((0.1 + 0.7) * 10)` возвращает значение `7` вместо `8`, которое ожидалось, поскольку внутреннее представление будет примерно таким: `7.9999999999999991118...`.

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

«Простое» объяснение даёт » руководство по числам с плавающей точкой, которое также называется «Why don’t my numbers add up?» («Почему мои числа не складываются?» — англ.)

### Преобразование в число с плавающей точкой

#### Из строк

Числовые строки или строки с начальной числовой последовательностью преобразовываются в значение с плавающей точкой, иначе строка преобразуется в целочисленное значение `0`.

#### Из других типов

При преобразовании значений других типов в число с плавающей точкой значение вначале преобразовывается в целое число (int), а затем в число с плавающей точкой (float). Дополнительную информацию о целочисленном преобразовании даёт раздел «Преобразование в целое число».

> Замечание:

> Поскольку поведение отдельных типов при преобразовании в тип int, то же самое происходит и при преобразовании в число с плавающей точкой (float).

### Сравнение чисел с плавающей точкой

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

Для сравнения чисел с плавающей точкой используется верхняя граница относительной ошибки при округлении. Эта величина называется машинной эпсилон или единицей округления (unit roundoff) и представляет собой самую маленькую допустимую разницу при расчётах.

Числа $a и $b равны до 5-ти знаков после точки.

Пример #1 Сравнение чисел с плавающей точкой

    <?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().

`↑` and `↓` to navigate • `Enter` to select • `Esc` to close • `/` to open