2009-12-07 90 views
1

我很困惑,爲什麼:php - 爲什麼floor會舍入一個整數?

echo log10(238328)/log10(62); 

結果在3

echo floor(log10(238328)/log10(62)); 

導致2

我知道地板幾輪下來,但我認爲這是隻爲十進制數。

如何從後面的表達中得到3個答案,同時仍然正常地舍入?

回答

10

PHP使用雙精度浮點數。兩個對數的結果都不能精確表示,所以分割結果並不精確。您得到的結果接近,但略小於3.當被格式化爲echo時,它會舍入到3。 floor,但是返回2

您可以通過採取的事實,即log(x, b)/log(y, b)相當於log(x, y)(對於任何鹼b)避免不精確分裂。這會給出表達式log(238328, 62),而其浮點結果恰好爲3(自238328起爲pow(62, 3)以來的正確結果)。

+1

+1表示日誌的數學標識 – Kenaniah 2009-12-13 02:24:36

6

如果你var_dump你會看到「3」實際上是一個浮點數。這意味着它可能接近3並且四捨五入。如果你想要3,你將不得不使用姐妹功能,ceil。

+0

的問題是..我想正常下降。但我發現這個實例是我的代碼中的一個錯誤,應該是一個整數,所以不應該向下舍入,但無論如何...:S – 2009-12-07 23:35:50

+0

我可以建議你使用像ceil(x-0.9)或類似的東西?這樣,它通常會向下舍入,但是當數字足夠接近時會向上舍入。或者也許ceil(x-0.999)? – luiscubal 2009-12-07 23:54:37

+0

這可能會工作...但它有點bodged ...有沒有辦法在PHP中準確地做到這一點? – 2009-12-07 23:56:18

9

這是由於浮點數在PHP中拋光的方式。

更多信息

一種解決方法是floor(round($value, 15));the PHP Manual's Floating Point Numbers entry。這樣做將確保您的號碼相當準確地打磨。

+0

啊......這是有道理的......任何人都知道一個替代函數,這意味着我可以準確地達到底線(log10(238328)/ log10(62)); – 2009-12-07 23:38:46

+0

因爲你需要有效的無限存儲器來存儲一個非理性的數字,例如log 10(238328),所以你不能準確地*取得很多浮點數 - 或者這個計算。你所能做的只是在下舍入之前添加一個「模糊因子」,以強制將下一個整數的幾乎整數值。 – bobince 2009-12-07 23:58:56

+0

'floor(round($ value,$ precision));' – Kenaniah 2009-12-08 00:16:20

1

使用round()函數和/或顯式將其轉換爲int而不是依賴ceil()可能會得到更好的結果。在這裏尋找更多信息:http://php.net/manual/en/language.types.integer.php

+0

顯式地從浮點數轉換爲整數與在該值上運行'floor()'的結果基本相同。 – Kenaniah 2009-12-08 06:43:32

1

在一點點性能爲代價,你可以強制它,通過四捨五入或字符串格式化的個數,從而精確到更多有用的範圍:

echo floor(round(log10(238328)/log10(62), 4)); 
echo floor(sprintf('%.4f', log10(238328)/log10(62))); 

// output: 
// 3 
// 3 

你應該去以您需要的最低精度。更精確的是而不是你想要什麼。沒有地板的倒圓可能會更加正確,結果會因精度而有所不同。

echo floor(round(log10(238328)/log10(62), 16)); 
echo round(log10(238328)/log10(62), 16); 
// output: 
// 2 
// 3 
1

有沒有做幾乎相同的三個功能:

  • 小區 - >ceil(0.2)==1 && ceil(0.8)==1
  • 地板 - >floor(0.2)==0 && floor(0.8)==0
  • 輪 - >round(0.2)==0 && round(0.8)==1