2015-11-23 36 views
1

我想讀取和xlsx文件批量導入到mysql數據庫。php excel讀取器讀取數字不正確

我可以成功讀取文本字段,但是當涉及到具有大量小數點的數字時,它會給出錯誤的結果。

從GitHub我使用諾沃/ spreadsheetreader

SpreadsheetReader.php SpreadsheetReader_XLSX.php

的index.php

$Reader = new SpreadsheetReader($orgFilename); 

$count = count($Reader); 

foreach ($Reader as $Row) 
{ 
    echo $Row[0] . '<br>'; 
} 

這裏是我的Excel數據

690835388.737296
-553772409.572704
16983999.9999999
16983999.9999999
-904762663.342704
0.439514518724299
89055169.9716966
171930071.634401
35291999.9999995
1151681063.10099

輸出是

690835388.7373
-553772409.5727
-904762663.3427
0.4395145187243
89055169.971697
171930071.6344
35291999.999999
1151681063.101

有誰知道爲什麼發生這種情況?

+0

是否將您的excel表值舍入? –

+0

雅,但是對於不同的值它是四捨五入的。你可以查看我的excel數據並在上面輸出。我想從excel數據中得到所有小數的確切數字 – Ahuson

+0

也許你可以在這裏提出問題。 https://github.com/nuovo/spreadsheet-reader/issues,以便作者可以解決您的問題。 –

回答

0

您偶然發現的問題與SpreadsheetReader無關。它完全基於excel和php中浮點數的不同精度。

了when我從你的例子中的一個號碼,簡單做:

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/16的1/2款項,1/4,1/8,...

對於0.25的上述例子,這很容易,因爲我們可以說它相當於1/4,它有一個乾淨的表示形式作爲二進制數(2^-2)。

不幸的是,事情並沒有如此順利的其他數字。如果我們試圖將0.3轉換爲二進制數,我們會遇到麻煩。這個數字沒有精確的二進制表示,因爲我們不能把它寫成不同的2^-N項的和。

計算機試圖通過找到一個接近大部分時間的表示來解決這個問題,甚至非常接近實數。這些表示有多好取決於用來存儲浮點數的位數。您投入的內存越多,代表性就越好。

就你的情況而言,excel只是使用更多的內存來存儲與你的php解釋器相比數字的小數部分。當您將這些數字從excel導入到php時,這會導致某種偏差。

編輯:

此問題的一個簡單的例子是分數1/3爲十進制數的表示。正如你可能知道沒有精確的表示,許多人只會寫0.3333333 ....並添加他們所需的3。如果我們想要在數字3的數字系統中編寫這個數字,那麼事情會變得非常簡單,因爲我們只會寫3^-1。

編輯2: 也許你可以嘗試導入這些大數字作爲可以有任意長度的PHP字符串。如果您只是使用php導入數據並希望存儲這些數據,這可能會有所幫助。可能會有一個完全不同的精度的數據庫。

編輯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