mit Schwimmer, Ihre Annahme $x == $x + 1
ist nicht unbedingt wahr:
$x=2;
echo ((float)($x+1)==(float)($x))?'EQUAL':'Not Equal';
ergibt "nicht gleich".
In den Konverter in den Kommentaren (http://www.h-schmidt.net/FloatConverter/IEEE754.html) verlinkt, können Sie dies reproduzieren. dezimal 2.0
ergibt 0x40000000
, dezimal 3.0
ergibt 0x40400000
, so dass sie in der Tat unterscheiden, wenn es um IEEE754 Float-Darstellung kommt.
Während z. B. dezimal 0.1
nicht als Float dargestellt werden kann: 0x3dcccccd
, die 0.10000000149011612
ist.
Was ist Dezimal 9223372036854775807
? Das ist 0x5f000000
, das ist 9.223372E18
, das 9223372180000000000
ist.
Was ist die Dezimalzahl 9223372036854775808
(PHP_MAX_INT + 1
)? Das ist 0x5f000000
, auch.
Was ist die Dezimalzahl 9223372036854776832
(PHP_MAX_INT + 1025
)? Das ist 0x5f000000
, auch.
Was ist Dezimal 9223372036854776833
(PHP_MAX_INT + 1026
)? Das ist 0x5f000000
, auch.
Sie sind alle gleich.
Während z. B. dezimal 9223373000000000000
(PHP_MAX_INT + 963145224193
)? Das ist 0x5f000001
, das ist 9.223373E18
, das ist 9223373000000000000
. Jetzt
, warum tut:
((float)($x+1025)==(float)($x+1026))?'EQUAL':'Not Equal';
yield "Nicht gleich"?
Sie fügen eine Ganzzahl zu PHP_MAX_INT
hinzu.
$x=PHP_INT_MAX;
$y=PHP_INT_MAX-1;
$z=PHP_INT_MAX+1;
var_dump($x);
var_dump($y);
var_dump($z);
ergibt:
int(9223372036854775807)
int(9223372036854775806)
float(9.2233720368548E+18)
PHP implizit ganzen Zahlen zu groß zu schweben umwandelt. Und das ist, wo Sie im Grunde genommen in PHP-Interna verloren sind (zumindest meiner Meinung nach), weil Sie von hier aus nie wissen werden, was passieren wird (ohne PHP-Interna zu kennen, fühlen Sie sich frei, mich zu korrigieren).
Hinweis dies:
$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);
ergibt:
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)
Wenn Sie eine ganze Zahl ($x+1026
) zu PHP_MAX_INT
hinzufügen, wird sie umgewandelt zu schweben, und wenn man einen Schwimmer hinzufügen ($x+1026.0
), es ist natürlich auch float. Aber offensichtlich sind sie intern nicht identisch, siehe die obigen Vergleiche.
Fazit:
- nicht schwimmt auf Gleichheit vergleichen
- über Ihre Abgüsse Vorsicht;
(float)($x+1026)
ist eine Ganzzahladdition und wird anschließend in float umgewandelt, während (float)($x+1026.0)
$x
in float konvertiert, dann den float 1026.0
hinzufügt und dann (überflüssig) in float umwandelt.
Edit: zusätzlich finden Sie unter:
Sie suchen beginnen müssen im [Bit-Level-Darstellung von Schwimmern] (https: // en. wikipedia.org/wiki/Floating_point) und dies hängt auch davon ab, ob Sie 32-Bit oder 64-Bit PHP –
welche PHP-Version haben Sie? mit meinem Test habe ich "nicht gleich" mit "$ x + 10" für zB – mmm
Werfen Sie einen Blick auf [diesen Konverter] (http://www.h-schmidt.net/FloatConverter/IEEE754.html), der Ihnen erlaubt um die Float-Darstellung für verschiedene Zahlen zu sehen –