我正在尝试阅读和xlsx文件批量导入到mysql数据库。
我可以成功读取文本字段但是当涉及到具有大小数点的数字时,它会给出错误的结果。
我正在使用github的 SpreadsheetReader.php
SpreadsheetReader_XLSX.php 的index.php 这是我的Excel数据 690835388.737296 输出 690835388.7373 有谁知道为什么会这样?$Reader = new SpreadsheetReader($orgFilename);
$count = count($Reader);
foreach ($Reader as $Row)
{
echo $Row[0] . '<br>';
}
-553772409.572704
16983999.9999999
16983999.9999999
-904762663.342704
0.439514518724299
89055169.9716966
171930071.634401
35291999.9999995
1151681063.10099
-553772409.5727
16984000个
16984000个
-904762663.3427
0.4395145187243
89055169.971697
171930071.6344
35291999.999999
1151681063.101
答案 0 :(得分:0)
您偶然发现的问题与SpreadsheetReader无关。它纯粹基于excel和php中浮点数的不同精度。
当我从你的例子中取出一个数字时,只需这样做:
echo 1151681063.10099;
然后输出为1151681063.101
。
每个软件都使用一定数量的内存来表示数字。一些内存用于表示数字的整数部分,一些数量用于表示分数部分。
对于整数来说很简单。每个十进制整数都可以表示为计算机所做的二进制数。他们做的算术数字是2的幂次数之和。
因此,例如,数字14可以表示为2 ^ 3 + 2 ^ 2 + 2 ^ 1 = 8 + 4 + 2 = 14.这适用于每个整数,只要您有足够的内存来存储它
对于小数,这是一个完全不同的故事。我们人类基于10的分数进行浮点计算。例如0.25 = 0.2 + 0.05 = 10 ^ -1 * 2 + 10 ^ -2 * 5.因此浮点数通过加1/10的倍数来设置,1 / 100,1 / 1000 ......
另一方面,计算机必须将这些数字表示为1 / 2,1 / 4,1 / 8,1 / 16 ......
对于0.25的上述示例,这很容易,因为我们可以说它相当于1/4,其具有干净的表示形式为二进制数(2 ^ -2)。
不幸的是,对于其他数字而言,事情并不顺利。如果我们尝试将0.3转换为二进制数,我们将遇到麻烦。这个数字没有精确的二进制表示,因为我们不能把它写成不同的2 ^ -N项的总和。
计算机试图通过找到一个在大多数时间内接近真实数字的表示来解决这个问题。这些表示的好坏在很大程度上取决于用于存储浮点数的位数。你投入的记忆越多,表现就越好。
在你的情况下,与你的php解释器相比,excel只使用更多的内存来存储数字的一小部分。当您将这些数字从excel导入php时,这会导致某种偏差。
编辑:
此问题的一个简单示例是将1/3分数表示为十进制数。你可能知道没有精确的代表,许多人只会写0.3333333 ....并根据需要添加3个。如果我们想要在数字系统中根据数字3编写这个数字,那么事情会变得非常简单,因为我们只需要编写3 ^ -1。
编辑2: 也许你可以尝试将那些大数字作为字符串导入,这些字符串可以在php中具有任意长度。如果您只是使用php导入数据并希望存储这些数据,这可能会有所帮助。 wihtin一个可能具有完全不同精度的数据库。
编辑3: 数字的精确度是通过php ini配置的,可以设置,参见http://php.net/manual/en/ini.core.php#ini.precision
编辑4:如果你想深入研究浮点精度的话题,那么这篇文章开头就是一篇非常好的文章:http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html