最近,我讀了一篇:Double or Nothing from GOTW by Herb Sutter 我有點困惑與以下程序的說明:瞭解周#67的宗師:雙人或沒有
int main()
{
double x = 1e8;
while(x > 0)
{
--x;
}
}
假設該代碼運行在某些機器上1秒鐘。我同意這樣的代碼是愚蠢的。
但是,如果我們將x
從float
更改爲double
,那麼在有些編譯器上,它會使計算機永遠運行。解釋基於以下標準引用。
從部分C++標準的3.9.1/8引用:
有三種浮點類型:浮點,雙精度和長一倍。 double類型至少提供與float相同的精度,long double類型的精度至少與double相當。 float類型的值的集合是類型double的值集合的子集;類型double的值集合是long double類型的值集合的子集。
的代碼的問題是:
多久你希望它如果你改變「雙」到「浮動」需要?爲什麼?
這裏給出的解釋:
它可能會採取或者約1秒(特定的實現浮動可能有點快,快,或增加了一倍略慢),或永遠取決於float是否可以精確地表示0到1e8之間的所有整數值。
標準的上述引用意味着可能存在可以用double表示的值,但不能用float表示。特別是在一些流行的平臺和編譯器中,double可以精確地表示[0,1e8]中的所有整數值,但float不能。
如果float不能準確表示從0到1e8的所有整數值?然後修改的程序將開始倒計時,但最終將達到不能被表示的值N和針對N-1 == N(由於浮點精度不足)...和
我的問題是:
如果float甚至不能代表1e8
,那麼當我們初始化float x = 1e8
時就已經溢出了;那麼我們如何才能讓電腦永久運行?
我想一個簡單的例子這裏(雖然不是double
但int
)
#include <iostream>
int main()
{
int a = 4444444444444444444;
std::cout << "a " << a << std::endl;
return 0;
}
It outputs: a -1357789412
這意味着,如果編譯器不能夠代表與int
類型的給定數量,這將導致溢出。
那麼我誤讀了嗎?我錯過了什麼?正在將x
從double
更改爲float
未定義的行爲?
謝謝!
感謝您的好信息,但我的問題是,如果我們在初始化時溢出,while循環甚至會啓動? – taocp
@taocp您在初始化時沒有溢出。浮點格式會隨着您達到更高值而持續降低*精度*,直到達到+ 1。#INF。對無限&#NAN的操作是合法的,而不是未定義的。他們可能會有意想不到的結果。看看[IEEE-754標準](https://en.wikipedia.org/wiki/IEEE_floating_point) –
@indeterminatelysequenced啊,非常感謝。 – taocp