你应该知道PHP浮点知识。

你应该知道PHP浮点知识。
PHP是一种弱类型语言。这样的特点必然要求无缝、透明的隐式类型转换,和PHP使用变量来存储任何类型的数值。机制的结构如下:(5.2)为例。

复制代码代码如下所示:

结构_zval_struct {

变量信息

zvalue_value值; / * * /

zend_uint引用计数;

zend_uchar型活跃型; / * * /

zend_uchar is_ref;

};
在上述结构中,实际保存价值本身是zvalue_value财团:

复制代码代码如下所示:

_zvalue_value { typedef联盟

长语句长值; / * * /

双双双值; / * * /

struct {

字符*;

Int len;

STR };

哈希表*哈希表值; / * * /

zend_object_value obj;

zvalue_value };
今天,我们只关心两个成员,语句和dval,我们应该意识到长语句与操作系统的编译器,不同长度的字的长度,它可能是32bits或64比特,双双(双精度)的IEEE 754规定是固定的,一定是64bits。

请记住这一点,PHP的一些代码的非平台独立性。Our next discussion, in addition to the particular point, assumes that long is 64bits

这里没有引用IEEE 754的浮点计数方法。你可以饶有兴趣地看到它。关键的一点是,双尾数是52位和1位的保存,有效隐藏53bits ..

在这里,它引出了一个非常有趣的问题。我们使用的C代码示例(假设长64位):

复制代码代码如下所示:

长x;

断言(a =(long)(double)a);
当A的值在什么范围内时,可以断言上面的代码(在文章的结尾)。

现在让我们回到要点上来。在执行脚本之前,PHP首先需要读取脚本并分析脚本。在这个过程中,机制也用于在脚本中,翻译字面量为例,下面的脚本:

复制代码代码如下所示:

< PHP

$ = 922337203685477580;64位的符号数最多。

$ = 922337203685477580; / + +的最大值1

var_dump(美元);

var_dump($);
输出:

复制代码代码如下所示:

Int(922337203685477580)

浮(9.22337203685e + 18)
换句话说,PHP在词法分析阶段,对于一个文字值,它将决定它是否超过了当前系统长的表值范围。如果不是,它将保存的语句,变量是is_long,否则它将代表dval,zval is_float ..

对于任何大于最大整数值的值,我们都必须小心,因为它可能会失去精度:

复制代码代码如下所示:

< PHP

$ = 922337203685477580;

$ = 922337203685477580;
var_dump($ =($ 1));
输出为false。

现在在讨论之前,开始说,PHP是一个32位整数,可能也可能是64,然后决定一些代码可以正常运行在64位,可能是因为隐藏类型转换,导致精度损失,导致代码不能正常运行,在32上系统。

因此,我们必须谨慎对待这个临界值,但是我们已经在PHP中定义了这个临界值:

复制代码代码如下所示:

< PHP

回声php_int_max;

>
当然,为了保险起见,我们应该使用字符串来拯救大整数,用数学函数库如bcmath计算。

此外,还有另一个关键配置将混淆我们。这是php.precision配置,这就决定了有多少有效位当PHP输出另一个浮点值。

最后,让我们回到上面提出的问题,即整数的长和最大值,这样我们就可以保证在长时间转向后,我们会回到浮点数,并且不会丢失精确性。

例如,对于整数,我们知道它是二进制表示法,101,现在,让我们有权,转1.01,给出高隐式有效1,我们得到二进制值5的双倍存储:

复制代码代码如下所示:

0 / / / * 10000000001 *指标位* / 0100000000000000000000000000000000000000000000000000
5的二进制表示,在部分结束时是最不损坏的,在这种情况下,从双返回到长,没有精确的损失。

我们知道,双使用52位表示尾数计算隐含的前1,这是53位精度。然后,如果长的整数值小于,我们就可以得到这个值:

复制代码代码如下所示:

2 ^ 53 - 1 = = 9007199254740991; / /记住,我们现在假设64bits长
所以,这个整数,当长时间的数值转换为双>长时,就不会丢失精度。

tag:知识浮点你应该知道电脑软件php

相关内容