Я полагаю, что есть выделенный цвет (похожий на розовый), который следует рассматривать не как цвет, а как прозрачность. Итак, вы рисуете первый, не рисуя пиксели розового цвета (то есть оставляя фон как есть), затем вы рисуете второй поверх него аналогичным образом, затем третий и так далее.
Try this as a quick fix:
$price_int = intval(floor($price_corrected + 0.5));
The problem you are experiencing is not PHP's fault, all programming languages using real numbers with floating point arithmetics have similar issues.
The general rule of thumb for monetary calculations is to never use floats (neither in the database nor in your script). You can avoid all kinds of problems by always storing the cents instead of dollars. The cents are integers, and you can freely add them together, and multiply by other integers. Whenever you display the number, make sure you insert a dot in front of the last two digits.
The reason why you are getting 114 instead of 115 is that floor
rounds down, towards the nearest integer, thus floor(114.999999999) becomes 114. The more interesting question is why 1.15 * 100 is 114.999999999 instead of 115. The reason for that is that 1.15 is not exactly 115/100, but it is a very little less, so if you multiply by 100, you get a number a tiny bit smaller than 115.
Here is a more detailed explanation what echo 1.15 * 100;
does:
The reason why PHP prints the surprising Corrected price = float(115)
(instead of 114.999...) is that var_dump
doesn't print the exact number (!), but it prints the number rounded to n - 2
(or n - 1
) digits, where n digits is the precision of the calculation. You can easily verify this:
echo 1.15 * 100; # this prints 115
printf("%.30f", 1.15 * 100); # you 114.999....
echo 1.15 * 100 == 115.0 ? "same" : "different"; # this prints `different'
echo 1.15 * 100 < 115.0 ? "less" : "not-less"; # this prints `less'
If you are printing floats, remember: you don't always see all digits when you print the float.
See also the big warning near the beginning of the PHP float docs.
Другие ответы рассмотрели причину и хороший обходной путь к этой проблеме, я считаю.
Чтобы попытаться решить проблему под другим углом:
Для хранения ценовых значений в MySQL, вам, вероятно, стоит взглянуть на тип DECIMAL , который позволяет хранить точные значения с десятичными разрядами.
PHP выполняет округление на основе значащих цифр. Это скрывает неточность (в строке 2). Конечно, когда появляется пол, он не знает ничего лучшего и все время опускается.