Проблемы с плавающей запятой в PHP

M
На сайте с 20.08.2004
Offline
376
1089

Знатоки выручайте - а то покрашусь скоро с этой проблемой!

собственно вот код для отладки

echo $dif_3point_and_middle_line."<br>";

if ($dif_3point_and_middle_line >= 0.4) echo $dif_3point_and_middle_line.">=0.4<br>";
if ($dif_3point_and_middle_line > 0.4) echo $dif_3point_and_middle_line.">0.4<br>";
if ($dif_3point_and_middle_line == 0.4) echo $dif_3point_and_middle_line."==0.4<br>";
if ($dif_3point_and_middle_line <= 0.4) echo $dif_3point_and_middle_line."<=0.4<br>";
if ($dif_3point_and_middle_line < 0.4) echo $dif_3point_and_middle_line."<0.4<br>";

if (intval($dif_3point_and_middle_line)) echo "intval<br>";
if (is_array($dif_3point_and_middle_line)) echo "is_array<br>";
//if (is_binary($dif_3point_and_middle_line)) echo "binary<br>";
if (is_bool($dif_3point_and_middle_line)) echo "is_bool<br>";
//if (is_buffer($dif_3point_and_middle_line)) echo "is_buffer<br>";
if (is_callable($dif_3point_and_middle_line)) echo "is_callable<br>";
if (is_double($dif_3point_and_middle_line)) echo "is_double<br>";
if (is_float($dif_3point_and_middle_line)) echo "is_float<br>";
if (is_int($dif_3point_and_middle_line)) echo "is_int<br>";
if (is_integer($dif_3point_and_middle_line)) echo "is_integer<br>";
if (is_long($dif_3point_and_middle_line)) echo "is_long<br>";
if (is_null($dif_3point_and_middle_line)) echo "is_null<br>";
if (is_numeric($dif_3point_and_middle_line)) echo "is_numeric<br>";
if (is_object($dif_3point_and_middle_line)) echo "is_object<br>";
if (is_real($dif_3point_and_middle_line)) echo "is_real<br>";
if (is_resource($dif_3point_and_middle_line)) echo "is_resource<br>";
if (is_scalar($dif_3point_and_middle_line)) echo "is_scalar<br>";
if (is_string($dif_3point_and_middle_line)) echo "is_string<br>";
//if (is_unicode($dif_3point_and_middle_line)) echo "is_unicode<br>";

результат!!! внимание!!!

0.4
0.4<=0.4
0.4<0.4
is_double
is_float
is_numeric
is_real
is_scalar

Что я не учел? Почему неправильные результаты?!

отец сыночка, лапочки дочки и еще одного сыночка
[Удален]
#1

а в чем проблема собственно?

M
На сайте с 20.08.2004
Offline
376
#2

проблема в том что

0.4<0.4 - не правильно

и нет 0.4==0.4 и 0.4>=0.4

ewg777
На сайте с 04.06.2007
Offline
225
#3

Мануал читали?

Довольно часто простые десятичные дроби вроде 0.1 или 0.7 не могут быть преобразованы в свои внутренние двоичные аналоги без небольшой потери точности. Это может привести к неожиданным результатам: например, floor((0.1+0.7)*10) скорее всего возвратит 7 вместо ожидаемой 8 как результат внутреннего представления числа, являющегося в действительности чем-то вроде 7.9999999999....
Это связано с невозможностью точно выразить некоторые дроби в десятичной системе счисления конечным числом цифр. Например, 1/3 в десятичной форме принимает вид 0.3333333. . ..
Так что никогда не доверяйте точности последних цифр в результатах с числами с плавающей точкой и никогда не проверяйте их на равенство. Если вам действительно необходима высокая точность, вам следует использовать математические функции произвольной точности или gmp-функции.
[Удален]
#4

да у пхп вообще с математикой, арифметикой и бинарными операция одни проблемы ..

M
На сайте с 20.08.2004
Offline
376
#5

у меня из базы беруться числа decimal (10,2)

Никаких дейсвий кроме умножения, сложения и вычитания не делается -а получается такая лажа.

Зачем тогда эти числа если нужно использовать gmp для сравнения. Да и тупо как-то.

Значение 0.4 как оно может быть каким-то другим?!

ewg777
На сайте с 04.06.2007
Offline
225
#6
Значение 0.4 как оно может быть каким-то другим?!


$a = 0.4;
var_dump(explode('.', $a) === explode('.', 0.4));
Обдурите пыху. Но это жесть.

А вообще есть:

echo bccomp('1', '2') . "\n";   // -1
echo bccomp('1.00001', '1', 3); // 0
echo bccomp('1.00001', '1', 5); // 1
[Удален]
#7
bearman:
да у пхп вообще с математикой, арифметикой и бинарными операция одни проблемы ..

прям как у меня 😂

[Удален]
#8

#rost, ты кстати писал чето, я появился :)

M
На сайте с 20.08.2004
Offline
376
#9

всем спасибо.

кому смог сказал спасибо и +

Miracle добавил 10.01.2010 в 12:04

блин, даже bccomp не всегда правильно работает

(float)$t1 36.6

(double)$t2 36.9

bccomp((double)$t1, (double)$t2) выдало 0.

задолбался и сделал так

$t1 = (int)10*$t1

$t2 = (int)10*$t2

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий