2014-02-06 33 views
2

我以前見過static_cast<int>(std::ceil(floatValue));向上舍入到一個整數,這有多可靠?

雖然我的問題是,我絕對可以指望這不是「不必要的」四捨五入嗎?我讀過一些整數不能用浮點數來完美表示,所以我擔心的是,當邏輯上不應該這樣做時,極小的「錯誤」會使ceil()向上舍入。不僅如此,而且一旦取整,我擔心代表中的一個小「錯誤」可能會導致數字略小於整數,導致cast轉換爲int來截斷它。

這難道沒有根據嗎?我記得有一段時間,python中的一個例子是打印一個特定的整數,這會導致它打印的東西很少(比如x.999,但我不記得確切的數字)

我需要的原因是請確保,我正在寫紋理緩衝區。常見的情況是整數作爲浮點數,但它偶爾會在需要四捨五入到包含它們的最接近的整數寬度和高度的值之間。它以2的冪次遞增,因此不必要的舍入成本可能導致應該只採用256x256紋理的紋理需要512x512紋理。

+0

這取決於'floatValue'的範圍。什麼*是*範圍? – NPE

+0

範圍是0.0到〜1024.0(我認爲我不需要擔心超出該範圍的值) –

+1

無法表示爲浮點數的整數將四捨五入爲另一個整數(某個倍數的倍數兩個),而不是稍微低於或高於整數的一部分。但是,一些算術(對於實數)會導致整數,可能會導致略小於或大於整數。然而,這與預先發生的事情無關。 – delnan

回答

2

我絕對可以指望這不是「不必要」的湊合嗎?我讀過一些整數不能完全浮點來表示,所以我擔心的是微乎其微的「錯誤」會欺騙小區()

是,一些大的數字是不可能的代表完全一樣浮點數字。在發生這種情況的區域中,所有浮點數都是整數。該錯誤不是微不足道的:如果出現錯誤,則由浮點表示整數的錯誤至少爲1。而且,顯然,在一些整數不能表示爲浮點的區域以及所有浮點數都是整數的區域中,ceil(f) == f

有問題的區域是| f | > 2 (16 * 1024 * 1024)適用於IEEE 754單精度和| f | > 2 適用於IEEE 754雙精度。

您更可能遇到的問題不是來自於以浮點格式表示整數的可能性,而是來自舍入錯誤的累積效應。如果您的編譯器提供了IEEE 754(浮點標準完全由現代且不太現代的英特爾處理器的SSE2指令實現)語義,那麼任何+, - ,*,/和sqrt操作都會導致數字完全表示爲浮點即使最終結果是一個整數並且可以精確表示,浮點計算也可能會偏離數學計算,但如果您應用的幾個操作沒有完全可表示的結果。然後你可能會得到一個稍微高於目標整數的浮點結果,並且會導致ceil()返回一些不同於你通過精確數學計算得到的結果。

有些方法可以確信某些浮點運算是精確的(因爲結果總是可表示的)。例如(double)float1 * (double)float2,其中float1float2是兩個單精度變量,總是精確的,因爲兩個單精度數字相乘的數學結果始終可表示爲double。通過以「正確」方式進行計算,可以最小化或消除最終結果中的錯誤。

2

範圍爲0.0〜1024.0〜

在此範圍內的所有整數可以準確地表示爲float,所以你會沒事的。

只有當你偏離24 bits of mantissa超出float所提供的範圍時,纔會有問題。

+0

但是這些問題將圍繞整數變成其他整數,而不是50億變成50億點9九九等。 – delnan

4

如果floatValue是確切的,那麼在代碼中四捨五入沒有問題。唯一可能的問題是溢出(如果結果不符合int)。當然,如此大的值,float通常不會有足夠的精度來區分相鄰的整數。

但是,危險通常在於floatValue本身並不準確。例如,如果它是精確答案是整數的某些計算的結果,則由於計算中的浮點舍入誤差,其最終結果可能會大於整數。

所以你是否有問題取決於你如何得到floatValue

+0

(+1)關於'floatValue'起源的要點。 – NPE