2012-04-27 122 views
13

有人可以解釋這種行爲嗎?我很清楚浮點數的機器級表示。這似乎與printf及其格式有關。 這兩個數字都完全由浮點符號表示(檢查:乘以64給出整數)。printf四捨五入行爲

#include <stdio.h> 
#include <iostream> 
using namespace std; 

int main() { 
    double x1=108.765625; 
    printf("%34.30f\n", x1); 
    printf("%9.5f\n", x1); 
    printf("%34.30f\n", x1*64); 

    double x2=108.046875; 
    printf("%34.30lf\n", x2); 
    printf("%9.5f\n", x2); 
    printf("%34.30f\n", x2*64); 
} 

輸出:

> 108.765625000000000000000000000000 
> 108.76562 
> 6961.000000000000000000000000000000 
> 108.046875000000000000000000000000 
> 108.04688 
> 6915.000000000000000000000000000000 

注意,第一個數字被捨去,而第二個被圍捕。

+1

您可能會對我的文章http://www.exploringbinary.com/inconsistent-rounding-of-printed-floating-point-numbers/感興趣。一些實現使用「從半個零開始」而不是「半到平均」。 – 2012-04-28 17:19:15

+0

似乎微軟在VS 2010和VS2015之間的一段時間內改變了他們的默認舍入行爲。我剛剛從一個升級到另一個,並得到一些非常惱人和微妙的錯誤。 [此博客](https://blogs.msdn.microsoft.com/vcblog/2014/06/18/c-runtime-crt-features-fixes-and-breaking-changes-in-visual-studio-14-ctp1 /)可能是爲了突出變化,但你完全可以原諒它。 – omatai 2016-10-10 04:52:05

+0

它取決於實現[在sprintf中基於Windows vs Unix的系統舍入差異](http://stackoverflow.com/q/4649554/995714),[C++爲與sprintf綁定的舍入行爲一致性](http:// stackoverflow。 com/q/31142600/995714) – 2016-11-02 04:29:51

回答

17

這是「一半甚至」或「銀行家的四捨五入」。即使數字恰好在兩者之間的一半處,圓形表示的最後一位數字也會被選中。

http://linuxgazette.net/144/misc/lg/a_question_of_rounding_in_issue_143.html
「對於GNU C庫,通過使用printf()的舍入規則是‘銀行家舍入’或‘舍入到偶數’這是比其他一些C庫更正確的,因爲C99規範表示。轉換爲十進制應使用當前所選的IEEE舍入模式(默認銀行家舍入)。「

+0

另外:http://www.gnu.org/software/libc/manual/html_node/Rounding.html – 2012-04-27 20:21:23

+1

鏈接文章的作者是無能的。 「二進制和十進制基數不共享同一組無理數」 - 這是無稽之談。理性/非理性獨立於基礎。 – 2012-04-27 21:47:59

+1

@R ..的確如此。但文章引用的段落是正確的,正如作者在[bug報告](http://sourceware.org/bugzilla/show_bug.cgi?id=4943)中痛苦地學到的那樣。 – 2012-04-28 01:53:01

0

%9.5f輸出給出了與源數最接近的小數點後面的5位數的數字。