Здравствуйте.
У меня есть несколько файлов с расширением .php, в которых содержится только один многомерный массив. Эти файлы подключаются к сценарию с помощью команды "include". Возникла проблема: в одном из массивов есть элемент, например, <code class="php">'capacity' => 0.2,</code>, но после подключения он отображается как <code class="php">'capacity' => 0.20000000000000001,</code>. Стоит отметить, что для целых чисел такого поведения не наблюдается — они выводятся без изменений.
Вот пример кода, который я использую:
<pre><code class="php">include ('...');
return $val;</code></pre>
Почему происходит такая ситуация, и как можно исправить вывод, чтобы значения приходили в том формате, в котором они указаны в массиве?
Спасибо.
Здравствуйте!
Проблема, которую вы наблюдаете, связана с особенностями представления дробных чисел в компьютерах. Дело в том, что большинство языков программирования (включая PHP) используют двоичное представление для чисел с плавающей точкой. Это может привести к небольшим точностным ошибкам, когда десятичные дроби не могут быть точно представлены в двоичной системе.
Когда вы задаете число `0.2`, оно не может быть представлено с абсолютной точностью в двоичной системе, что приводит к тому, что в некоторых случаях вы видите `0.20000000000000001` вместо ожидаемого `0.2`. Это также может произойти с другими дробными числами, поэтому такая проблема является общей для работы с числами с плавающей запятой.
### Способы исправления:
1. **Форматирование при выводе:** Вы можете использовать функцию `number_format()`, чтобы контролировать количество знаков после запятой при выводе значений. Например:
```php
echo number_format($array['capacity'], 1);
```
Это выведет `0.2`, ограничивая число знаков после запятой до одного.
2. **Функция `round()`:** Если вам нужно округлить значение, вы можете использовать функцию `round()`:
```php
$val = round($array['capacity'], 1); // Округляем до одного знака после запятой
```
3. **Использование строк вместо чисел:** Если числа не требуют математических операций, можно хранить их как строки:
```php
'capacity' => '0.2',
```
Это избавит от проблемы с представлением дробных чисел, но требует осторожности при последующих вычислениях.
Каждый из этих методов может быть подходящим в зависимости от вашего конкретного случая использования. Если вы просто хотите избежать отображения «лишних» значений, я рекомендую использовать `number_format()` или `round()`, так как они просты и эффективны для форматирования вывода.
Потому что у вас числа с плавающей запятой. <br/>
Тебе исчерпывающе ответили о причинах, такова природа десятичных чисел, которые хранятся в битах. <br/> <br/> Если тебе нужно работать с числами в той форме что сохранена - либо используй строки. <br/> <code class="php">'capacity' => "0.2",</code> <br/> либо используй целочисленный формат с фиксированной степенью (где то ты должен определить предел точности, сколько знаков после запятой, которые тебя интересуют, и делай на это соответствующую скидку при операциях умножения и деления). <br/> <code class="php">'capacity' => 2000,</code> <br/> В данном случае речь о 4 значимых цифрах или 10^4 <br/> при умножении, результат нужно делить на 10^4 и отбрасывать все что после запятой через intVal или round (а перед делением наоборот первый операнд умножать) <br/> <br/> Внимание, на php int, при превышении PHP_INT_MAX будет автоматически сконвертировано в float, поэтому даже с этим методом придется хранить числа в строках и использовать <a href="https://www.php.net/manual/en/book.bc.php" rel="nofollow">bc math</a> или рекомендуют <a href="https://www.php.net/manual/en/book.gmp.php" rel="nofollow">gmp</a> как самую быструю реализацию