Php 浮点,何时出现,如何工作

Php 浮点,何时出现,如何工作,php,floating-point,Php,Floating Point,据我所知,float可以精确地表示14个数字 那么,让我们假设我们有 a = 564214623154 b = 54252 c = 30609771735350808 d = 30609761111111111 我们乘以这个 c=a*b,它应该是30609771735350808,但编译时显示为3.0609771735351E+16 据我所知,它应该会失去一些精度,但当我用a除以c时 c/a我得到564214623154精确结果,没有任何精度损失 另一个例子是我们有 a = 5642146

据我所知,float可以精确地表示14个数字

那么,让我们假设我们有

a = 564214623154
b = 54252
c = 30609771735350808 
d = 30609761111111111
我们乘以这个 c=a*b,它应该是30609771735350808,但编译时显示为3.0609771735351E+16 据我所知,它应该会失去一些精度,但当我用a除以c时 c/a我得到564214623154精确结果,没有任何精度损失

另一个例子是我们有

a = 564214623154
b = 54252
c = 30609771735350808 
d = 30609761111111111
e=c-d应为10624239697,但编译时显示为10624239696,因此精度损失

那么,只有当我减去或添加两个数字时,精度才会降低吗


如果重要的话,我使用php,乘法和除法也可能会失去精度。PHP和JavaScript以IEEE-754格式存储数字,尾数为52位,指数为11位。有些整数是精确表示的,有些则不是

让我们试试这些:

在真实数学中(使用Ruby生成):

在PHP和JavaScript中

45345657434523 * 9347287748322342 / 74387422372 = 5697991604786168000
所以我们的乘法和除法也会失去精度

编辑:在重温OP的问题时,这似乎不是一个很好的答案,因为结果包含超过15位小数精度。如果问题的目的是将一组数字相乘或相除,每个数字的精度是15位还是更低,那么最终结果往往会保持相当高的精度(前提是不溢出或下溢)。因此,您可以将
1.25E35*2.5E7
相乘,得到精确的
3.125e+42
,因为PHP和JavaScript基本上会将有效数字组相乘,并将指数相加。但是,如果将这两个值相加,将得到
1.25E35+2.5E7=1.25E35
。没错,你在一个数字上加了2500万,它不会改变!这是因为,正如OP所说,你只能得到14或15位小数精度。尝试手动将这两个值相加,方法是写出
120000000000000000000000+25000000
。14-15位数字从左边开始计数,您无法全部拾取


底线是加减法更容易出现精度问题。注意这一点很好。

在第一种情况下,您不会失去精度,PHP只是将较大的数字格式化为浮点数。(内部数字保持为浮点数。)尝试此操作以获得“精确”输出:

接下来,在
c*d
的情况下,您的两个数字各自已经超过了标准IEEE-64位浮点(53位,而您至少需要55位)的容量,因此存储这些数字时,精度已经丢失

在加法/减法过程中丢失精度的问题称为“取消”:所有占用存储空间的最重要位都被取消,最终没有足够的精确位来填充manitssa。这就是生活


想象一下,你坐在月球上,在英国伍斯特对你兄弟的胡须和头发长度进行了两次测量。比较这两个测量值会使您需要存储大量精度。

不要忘记IEEE754中的隐藏位。你实际上有53个尾数可用。@Kerrek-谢谢,是的,53个尾数可用@Templar-是一个很好的起点,或者谷歌“ieee 754”搜索其他页面。@Templar:I就是这样做的:它将
$c
视为一个整数,并将其作为整数打印。但是,如果数字在内部存储为双倍,则必须使用通常的盐量,也就是说,您的值可能没有打印的有效数字那么多。