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...