PHP PDO-запрос возвращает неточное значение для полей FLOAT

Я предполагаю, что это произошло раньше, но я не смог найти ответ на мой вопрос. Вот небольшой фрагмент кода:

$stmt = $this -> db -> query(" SELECT `Field` FROM `Table` WHERE (`ID` = 33608)"); var_dump($stmt -> fetch()); 

И это результат, который я получаю:

  array(1) { ["Field"]=> float(1.7999999523163) } 

Однако данные в базе данных MySQL составляют 1,8. Тип поля – float (7,4). $ this-> db – объект PDO. Недавно я перешел на PDO (из AdoDB), и этот код работал нормально. Я не уверен, что пошло не так. Не могли бы вы указать мне в правильном направлении? Благодаря!

Как указано в типах с плавающей запятой (приблизительное значение) – FLOAT , DOUBLE :

MySQL выполняет округление при сохранении значений, поэтому, если вы вставляете 999.00009 в 999.00009 FLOAT(7,4) , приблизительный результат равен 999.0001 .

Поскольку значения с плавающей запятой являются приблизительными и не сохраняются в виде точных значений, попытки рассматривать их как точные в сравнении могут привести к проблемам. Они также зависят от зависимостей платформы или реализации. Для получения дополнительной информации см. Раздел C.5.5.8, «Проблемы с значениями с плавающей запятой»

Для максимальной переносимости код, требующий хранения приблизительных значений числовых данных, должен использовать FLOAT или DOUBLE PRECISION без указания точности или количества цифр.

Поэтому при вставке 1.8 в вашу базу данных MySQL округлял литерал до 001.8000 и кодировал ближайшее приближение к этому номеру в формате binary32 : то есть 0x3FE66666 , чьи биты означают:

 Знак : 0b0

 Предвзятый показатель : 0b01111111
                = 127 (представление включает смещение +127, поэтому exp = 0)

 Значение : 0b [1.] 11001100110011001100110
                     ^ скрытый бит, не сохраненный в двоичном представлении
                = [1.] 7999999523162841796875

Это соответствует:

  (-1) ^ 0 * 1.7999999523162841796875 * 2 ^ 0
 = 1,7999999523162841796875

Это значение, которое MySQL возвращает клиенту. Похоже, что AdoDB затем проверял тип данных столбца и соответствующим образом округлял результат, тогда как PDO этого не делает.

Если вам нужны точные значения, вы должны использовать тип данных с фиксированной точкой , например DECIMAL .

Вы должны использовать тип поля DECIMAL вместо FLOAT если хотите точные значения.
И PDO не имеет к этому никакого отношения. Это скорее связано с тем, как компьютеры работают в целом.