Avec flotteur, votre hypothèse $x == $x + 1
est pas nécessairement vrai:
$x=2;
echo ((float)($x+1)==(float)($x))?'EQUAL':'Not Equal';
cède "Different".
Dans le convertisseur lié dans les commentaires (http://www.h-schmidt.net/FloatConverter/IEEE754.html), vous pouvez reproduire cela. 0x40000000
, la décimale 0x40000000
, donne donne 0x40400000
, donc ils sont en effet différents quand il s'agit de la représentation flottante IEEE754.
Considérant que, par exemple, la décimale 0.1
ne peut pas être représentée comme flottant: 0x3dcccccd
, qui est 0.10000000149011612
.
Quel est le nombre décimal 9223372036854775807
? C'est 0x5f000000
, qui est 9.223372E18
, qui est 9223372180000000000
.
Quelle est décimal 9223372036854775808
(PHP_MAX_INT + 1
)? C'est aussi 0x5f000000
.
Quelle est décimal 9223372036854776832
(PHP_MAX_INT + 1025
)? C'est aussi 0x5f000000
.
Quelle est décimal 9223372036854776833
(PHP_MAX_INT + 1026
)? C'est aussi 0x5f000000
.
Ils sont tous les mêmes. Considérant que, par exemple: décimal 9223373000000000000
(PHP_MAX_INT + 963145224193
)?
C'est 0x5f000001
, qui est 9.223373E18
, qui est 9223373000000000000
.
Maintenant, pourquoi:
((float)($x+1025)==(float)($x+1026))?'EQUAL':'Not Equal';
rendement "Different"?
Vous ajoutez un entier à PHP_MAX_INT
.
$x=PHP_INT_MAX;
$y=PHP_INT_MAX-1;
$z=PHP_INT_MAX+1;
var_dump($x);
var_dump($y);
var_dump($z);
rendements:
int(9223372036854775807)
int(9223372036854775806)
float(9.2233720368548E+18)
PHP convertit implicitement entiers trop gros pour flotter. Et c'est là que vous êtes fondamentalement perdu en interne PHP (du moins à mon avis), car à partir de là, vous ne saurez jamais ce qui va se passer (sans connaître les internes PHP, n'hésitez pas à me corriger, cependant).
Avis ceci:
$x=PHP_INT_MAX;
$a=(float)($x+1025.0); // 1025 float
$b=(float)($x+1026.0); // 1026 float
$c=(float)($x+1025); // 1025 int
$d=(float)($x+1026); // 1026 int
var_dump($x);
var_dump($a);
var_dump($b);
var_dump($c);
var_dump($d);
var_dump($a==$b);
var_dump($a===$b);
var_dump($c==$d);
var_dump($c===$d);
rendements:
int(9223372036854775807)
float(9.2233720368548E+18)
float(9.2233720368548E+18)
float(9.2233720368548E+18)
float(9.2233720368548E+18)
bool(true)
bool(true)
bool(false)
bool(false)
Si vous ajoutez un entier ($x+1026
) à PHP_MAX_INT
, il est converti en flotter, et lorsque vous ajoutez un flotteur ($x+1026.0
), il flotte aussi, bien sûr. Mais, évidemment, ils ne sont pas les mêmes en interne, voir les comparaisons ci-dessus.
Bottom line:
- Ne pas comparer les flotteurs pour l'égalité
- Faites attention à vos moulages;
(float)($x+1026)
est une addition entière, puis lancée pour flotter, tandis que (float)($x+1026.0)
convertit $x
pour flotter, puis ajoute le flotteur 1026.0
, puis jette (en superflue) pour flotter.
Edit: en plus, voir:
Vous devez commencer à regarder le (https [représentation au niveau binaire de flotteurs]: // en. wikipedia.org/wiki/Floating_point) et cela variera aussi selon que vous exécutez PHP –
32 bits ou 64 bits quelle version de PHP avez-vous? avec mon test j'ai "pas égal" avec "$ x + 10" par exemple – mmm
Jetez un oeil à [ce convertisseur] (http://www.h-schmidt.net/FloatConverter/IEEE754.html), ce qui vous permet pour voir la représentation flottante pour les différents nombres –