Почему на PHP PHP преобразует результат (int) ((0.1 + 0.7) * 10) в 7, а не 8?

Почему на PHP PHP преобразует результат (int) ((0.1+0.7)*10) в 7, а не 8? Я знаю, что результат будет (float) 8 когда он будет передан (int) результат будет равен 7? Почему это происходит?

Это все о float . См. PHP: Числа с плавающей запятой :

Предупреждение – точность с плавающей точкой

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

Кроме того, рациональные числа, которые точно представлены в виде чисел с плавающей запятой в базе 10, например 0,1 или 0,7, не имеют точного представления в виде чисел с плавающей запятой в базе 2, которые используются внутри, независимо от размера мантиссы. Следовательно, они не могут быть преобразованы в их внутренние двоичные копии без небольшой потери точности. Это может привести к запутывающим результатам: например, пол ((0,1 + 0,7) * 10) обычно возвращает 7 вместо ожидаемого 8, так как внутреннее представление будет чем-то вроде 7.9999999999999991118 ….

Поэтому никогда не доверяйте значениям с плавающим числом до последней цифры и не сравнивайте числа с плавающей запятой непосредственно для равенства. Если требуется более высокая точность, доступны произвольные математические функции точности и функции gmp.

Дополнительное чтение:

  • Что каждый компьютерный ученый должен знать о арифметике с плавающей точкой
  • Насколько опасно сравнивать значения с плавающей запятой?
  • Почему десятичные числа не могут быть представлены точно в двоичном формате?

Ответ Галлея велик.

Дополнительная информация, в которой вы нуждаетесь, заключается в том, что приведение в int всегда усекает десятичные числа, независимо от того, насколько они близки к следующему числу. Итак (int) 7.999999999999 будет 7.

Часто принято округлять, когда вы бросаете, чтобы добраться до ближайшего, например

 (int) (x + 0.5) 

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