Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/249.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PHP中改变简单数字的值_Php_Casting_Floating Point_Int_Precision - Fatal编程技术网

在PHP中改变简单数字的值

在PHP中改变简单数字的值,php,casting,floating-point,int,precision,Php,Casting,Floating Point,Int,Precision,我使用的是一个Money类,它要求所有货币都在int中才能实例化它。发生的情况是,我遇到了一个特定的数字(我尝试了各种其他数字,一切都按预期进行),当类型从float转换为int时,该数字的值不同 由于浮点数的性质,我可能期望这是一个非常高精度的数字,但这没有任何意义,下面是我如何重现错误的 $value = (float)9.78; var_dump($value ); $prec = (int)(100); var_dump($prec); $value = $value * $prec;

我使用的是一个Money类,它要求所有货币都在
int
中才能实例化它。发生的情况是,我遇到了一个特定的数字(我尝试了各种其他数字,一切都按预期进行),当类型从
float
转换为
int
时,该数字的值不同

由于浮点数的性质,我可能期望这是一个非常高精度的数字,但这没有任何意义,下面是我如何重现错误的

$value = (float)9.78;
var_dump($value );
$prec = (int)(100);
var_dump($prec);
$value = $value * $prec;
var_dump($value);
var_dump((int)($value));
。。。这将产生以下输出

float(9.78)  /* $value as a float */
int(100)     /* $prec as an int */
float(978)   /* $value * $prec as a float, all going well... */
int(977)     /* $value type cast to an int ???????? */
。。。这到底是怎么回事为什么在这种情况下,
$value
类型转换为
int
会产生不同的值?


编辑:我之所以不接受此副本,是因为我需要的答案没有出现在其他线程中。这就是:我必须像这样申请
round()

$dec_precision = strlen((string)($prec)-1);
$value = round($value * $prec, $dec_precision);

希望这对别人有帮助

PHP使用浮点数的指数表示,因此它不精确。阅读:

浮点数的精度有限。尽管这取决于 PHP系统通常使用IEEE 754双精度格式, 由于顺序的四舍五入,这将给出最大的相对误差 第1.11e-16节。非初等算术运算可能会产生更大的错误 错误,当然,当发生错误时,必须考虑错误传播 一些行动是复杂的

此外,有理数 可以精确表示为以10为底的浮点数,如 0.1或0.7,则在基2中没有浮点数的精确表示形式,而基2中的浮点数是内部使用的,无论基的大小 尾数。因此,它们不能转换为内部二进制文件 精确性损失不大的对应项。这可能导致 令人困惑的结果:例如,地板((0.1+0.7)*10)通常 返回7而不是预期的8,因为内部表示 大概是7.9999999999991118

UPDv1:


请注意PHP:BCMath和GMP。

伙计,我对浮点的理解有点离谱,我当时(未受过教育)的假设是,在实际处理高精度数字之前,ε不会是一个问题,但事实上,根据文档,即使是0.1也很容易受到影响。我想我只需要再做一次RTFM。