Var*_*ish 5 php floating-point floating-accuracy floating-point-precision
<?php
$x=PHP_INT_MAX;
echo ((float)($x+1026)==(float)($x))?'EQUAL':'Not Equal';
Run Code Online (Sandbox Code Playgroud)
我知道浮点运算不精确,$ x和$ x + 1非常接近,它们四舍五入到相同的浮点值,如果你使用1到1025之间的任何数字,它只显示输出为EQUAL如果你使用1025以上的值,它将开始输出'Not Equal'.我想知道为什么?它背后的原因是什么?为什么只在1025之后?
对于浮动,您的假设$x == $x + 1不一定正确:
$x=2;
echo ((float)($x+1)==(float)($x))?'EQUAL':'Not Equal';
Run Code Online (Sandbox Code Playgroud)
产生“不等于”。
在评论中链接的转换器(http://www.h-schmidt.net/FloatConverter/IEEE754.html)中,您可以重现此内容。十进制2.0收益率0x40000000,十进制3.0收益率0x40400000,所以当涉及到 IEEE754 浮点表示时它们确实是不同的。
然而,例如,decimal0.1不能表示为 float: 0x3dcccccd,即0.10000000149011612。
什么是小数9223372036854775807?那是0x5f000000,那是9.223372E18,那是9223372180000000000。
什么是小数9223372036854775808(PHP_MAX_INT + 1)?那0x5f000000也是。
什么是小数9223372036854776832(PHP_MAX_INT + 1025)?那0x5f000000也是。
什么是小数9223372036854776833(PHP_MAX_INT + 1026)?那0x5f000000也是。
他们都是一样的。
然而,例如:十进制9223373000000000000( PHP_MAX_INT + 963145224193)?那是0x5f000001,那是9.223373E18,那是9223373000000000000。
现在,为什么:
((float)($x+1025)==(float)($x+1026))?'EQUAL':'Not Equal';
Run Code Online (Sandbox Code Playgroud)
产量“不等于”?
您正在向 中添加一个整数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);
Run Code Online (Sandbox Code Playgroud)
产量:
int(9223372036854775807)
int(9223372036854775806)
float(9.2233720368548E+18)
Run Code Online (Sandbox Code Playgroud)
PHP 隐式转换太大而无法浮点的整数。这就是你基本上迷失在 PHP 内部结构中的地方(至少在我看来),因为从这里开始,你永远不会知道会发生什么(如果不知道 PHP 内部结构,请随时纠正我)。
请注意这一点:
$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);
Run Code Online (Sandbox Code Playgroud)
产量:
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)
Run Code Online (Sandbox Code Playgroud)
如果你添加一个整数 ( $x+1026) 到PHP_MAX_INT,它就会转换为浮点型,当你添加一个浮点型 ( $x+1026.0) 时,它当然也是浮点型。但是,显然,它们的内部并不相同,请参见上面的比较。
底线:
(float)($x+1026)是整数加法,然后转换为 float ,而(float)($x+1026.0)转换$x为 float ,然后添加 float 1026.0,然后(多余地)转换为 float 。编辑:另外,请参阅: