2013-02-23 55 views
0

我正在一個項目,並完成它我需要做一些比較雙,浮法... 問題是,當我比較兩個雙分別是最大值一張雙人牀和一個雙+ 1的最大價值,比較失敗... 我做爲什麼我的雙重比較失敗C++

if (std::max(d_max + 1.1, (d_max)) == d_max) 
    std::cout << "bad" << std::endl; 

功能最多的答案是D_MAX和「壞」顯示... 是具有人想法還是解決方案,以便比較我的精確度? 我檢查了谷歌,但我發現更多的解釋比我的問題真正的解決方案... 非常感謝!

+6

目前還不清楚你在這裏期待什麼。如果'd_max'是'double'的最大值,那麼你不會得到比它高的任何東西。 – 2013-02-23 14:05:52

+0

最大... <在這裏插入Inigo Montoya報價> – 2013-02-23 14:07:05

+0

是不是可以比較一個double的最高值與另一個沒有type的值? – bottus 2013-02-23 14:07:53

回答

7

C++中的所有對象都有一個類型。 d_max的類型是doubled_max + 1.1的類型仍然是雙倍的。如果d_maxdouble的最大值,那麼d_max + 1.1不可表示,並且將使用最接近的可表示值,即d_max(但是,如果添加明顯更大的值,則最接近的可表示值被認爲是正無窮大)。所以,你的std::max調用等效於:

std::max(d_max, d_max) 

爲了證明:

double d_max = std::numeric_limits<double>::max(); 
bool b = (d_max == (d_max + 1.1)); 
std::cout << std::boolalpha << b << std::endl; 

這給true作爲輸出。


在回答您的意見,我認爲你正在做的事情是這樣的:

double d_max = std::numeric_limits<double>::max(); 
long double ld = d_max + 1; 
std::cout << (d_max == ld) << std::endl; 

而且奇怪的是,你會發現明顯d_maxld是相等的。爲什麼?那麼d_maxdouble。當您執行d_max + 1時,操作結果也是double - 如前所述,d_max + 1的值不能用double表示,因此選擇最接近的可表示值(d_max)。然後將該值分配給ld

請注意,這不太可能通過確保運算符產生long double(可能與d_max + 1.0L)得到解決。在如此巨大的數字(大約10^308帶有IEEE 754表示)時,加1將不會將您移動到long double中的下一個可表示值。我的執行,我要補充10 (也就是1後面有289個零)以實際使值的變化:

double d_max = std::numeric_limits<double>::max(); 
long double ld = d_max + 1E289L; 
std::cout << (d_max == ld) << std::endl; 

此外,也不能保證long doubledouble更精確。唯一的保證是它不具有精度較低的

+0

我明白你的意思,但即使我沒有使用最大函數進行比較,我也會比較一個double值和一個long值,它們分別代表值:max雙倍和最大值的雙+ 1,我得到的錯誤比以前...這就是我不明白。如果我不犯任何錯誤,長雙重比雙倍大,不是嗎? – bottus 2013-02-23 14:17:31

+0

@bottus看我的編輯。 – 2013-02-23 14:27:30

+0

@bottus - 不要認爲'long double'大於'double'。覈實。使用'std :: numeric_limits :: max()'。 – 2013-02-23 14:27:42

1

讓我們假裝雙打表示爲十進制浮點數,科學記數法。然後,d_max會像

9.999999999999999999 ⋅ 10⁹⁹ 

現在讓我們添加1.1到:

9.999999999999999999 ⋅ 10⁹⁹ + 1.1 
= 999999999999999999900000000...000 + 1.1 
= 999999999999999999900000000...001.1 

一輪到20,甚至40顯著數字(你必須爲這些類型,甚至長雙,只有有限的信息能力),你得到...?再次,d_max


注意,同樣適用於減法一樣,所以

int main() { 
    long double d_max = std::numeric_limits<double>::max(); 
    if(d_max == d_max - 1.1) 
    std::cout << " d_max  = " << d_max 
      << "\n== d_max - 1.1 = " << d_max + 1.1 << std::endl; 
    return 0; 
} 

輸出

d_max  = 1.79769e+308 
== d_max - 1.1 = 1.79769e+308 

即這真的沒有什麼關係d_max是提供最大的價值,但它是比你添加的要大得多。

+0

好吧,我很好理解你的解釋;)我所做的目標是管理我的程序中的下溢和溢出。我需要做一些操作,比如*,/ ......我能做的最大操作是double的double * max值的最大值。好的。但我想管理溢出到分配。我的意思是如果我做一個像雙測試= 1000000000000000的小測試;我的程序不應該崩潰,我真的不知道該怎麼做......當我發現限制時,我認爲它會是足夠的,但它似乎不是。你知道是否可以管理嗎?謝謝 – bottus 2013-02-23 14:38:48

+0

我不明白你到底想要做什麼。 – leftaroundabout 2013-02-23 14:42:18

+0

我試圖抓住有可能獲得溢出或下溢。我的項目是在不同類型之間做一些操作。當您嘗試直接在程序中爲類型賦值時,編譯器不會讓您這樣做。但我使用像float(2.324)double(5.15154)mul(用於乘法)的文件配置來完成它可能會在文件中產生荒謬的價值,編譯器不會看到它,那麼我需要檢查之前指定是否存在欠缺或溢出;) – bottus 2013-02-23 14:49:11