現代C 中取整函式確保準確嗎?

時間 2021-09-09 10:09:06

1樓:華研

我怎麼莫名想起有一條浮點彙編指令是專門用來取整的呢?

(你還能不相信硬體

如果你愣是寫了乙個2.9999999999999999999999998進去取整,百分百得到乙個3.

浮點數實際上由兩個部分組成:階碼和尾數(兩數各有一位的符號)。

這裡舉個例子(計算機硬體的實際運算會略有出入,編碼方式不一定相同):

我們可以用5位的階碼和3位的尾數,共8位乙個位元組來表示乙個浮點數,比如1 1111 1 11就是指-0.001111 或者是 1.111 E -3.

化為十進位制為0.234375.

由於乙個浮點數的位數有限,自然精度也有限,以上面的表示方法為例,可表示的最小正數為0 0001 1 11即0.000001(十進位制0.15625) ,最大正數為 0 1111 0 11即1111(十進位制15),精度為4個二進位制有效數字。

那麼向下取整是怎麼進行的呢?

舉個例子浮點數 0 1110 0 01取整:

0 1110 0 01 -- > 00001110<<00000001 -- > 00011100

又比如 0 1111 1 10:

0 1111 1 10 -- > 00001111<<11111110 -- > 00000011

(相信你認識 << 運算子,也知道補碼這種東西)

實際上在程式中,浮點常數會直接轉化成2進製,所以像2.9999999999999999這類有可能就會直接轉化為3存進去,取整結果自然為3. 使用者輸入時也是自動按精度擷取。

所以,寫軟體也應該了解一些計算機的基礎知識,如果你知道就不會問這個問題了。畢竟取整可不可靠主要是跟硬體有關,實在不行就提高計算精度吧(比如考慮一下寫乙個跟BigDouble一樣的類)。

2樓:Aman

如果要自己寫的話,考慮到負數,應該寫為(假設你的入參在 int 能表達的範圍內):

intmy_round

(doublea)

你擔心的情況不會發生,因為 C 的 round 實現等價於(是不是如出一轍?):

double

round

(doublex)

如果你的編譯器支援 C99 或 C++11,你可以使用 lroundf[1]

[2],直接返回整數,這樣就不繁瑣啦。

3樓:

浮點數的表示方法,浮點數向整數的轉換規則是由IEEE754規定的,這個規範目前幾乎被所有程式語言遵守。C++在這上面沒有魔法。

4樓:獨銘鳴

我曾經,因為ceil精度問題,wa了一次,從此取整。用1+(m-1)/n代替ceil(m/n)。關於整數除法的上取整。對於一般的浮點數。還是用+0.5那個

5樓:

上述過程可以確保n為3嗎?

可以,當然前提是:a是個規格化數,且其值在int的可表達範圍內

假設a的真實值為2.99999998

a的值不可能是2.99999998,因為C語言規定round返回的值必須是浮點格式的整數值

是否應該寫成如下形式:int n = static_cast(a + 0.5);

這是典型的錯誤做法。假如 double a = 0.49999999999999994,你會得到 a<0.

5 為真,但static_cast(a + 0.5)卻等於1的可笑結果。還是老老實實的用round函式吧,它能得到正確的四捨五入結果0。

C++是如何保證 n=3 的呢?

這跟C++沒有關係,二進位制浮點數標準(IEEE 754)保證可以準確描述整數數值,也就是浮點數的3.0就是實數3.0,不會是實數2.

9999……8或3.000……1。再說了,如果C++保證不了,那其它語言也同樣沒辦法。

C 中是否允許在函式中定義函式?

暗能量泡泡 C 不能支援直接在函式中定義函式。C 11通過支援Lambda函式 實際上是個匿名class的物件 來實現類似功能。其他方式可以使用函式中定義struct class的方式再定義其靜態成員函式的方式來模擬一樣的效果。 Johnny Wong 可以使用class struct的實現,它們支...

c 中函式宣告時使用void函式名(函式型別)是什麼意思 為什麼要這樣宣告函式?

你看那銳雯 首先去驗證。你測試一下乙個不需要返回值的函式不寫void,會發生什麼?報什麼錯就會發現如果不寫編譯器會認為那你需要返回 int 第二,仔細研究c語言的函式返回值語法,以及同樣類似的問題,編譯器找不到函式宣告會發生什麼?這個時候編譯器是如何判定返回值型別的?這些都在c標準規定了,當然有些是...

為什麼C 中沒有階乘函式?

呂不鬧 如果只是問為什麼,那麼答案應該是 委員會那些老學究不允許太多無關緊要的功能進入標準。可能他們覺得 CPPer 都能自己寫出來吧。 簡易版 include include include include include using namespace std intmain O 1 版 inc...