我想在特定的計算機上找到尾數位數和單位舍入數。我瞭解這些是什麼,只是不知道如何找到它們 - 儘管我知道它們可以因計算機而異。如何找到特定機器上的尾數長度?
我需要這個數字來執行數值分析的某些方面,比如分析錯誤。
我目前的想法是我可以編寫一個小的C++程序來緩慢增加一個數字,直到發生溢出,但我不確定使用什麼類型的數字。
我在正確的軌道上嗎?一個人究竟如何計算這個?
我想在特定的計算機上找到尾數位數和單位舍入數。我瞭解這些是什麼,只是不知道如何找到它們 - 儘管我知道它們可以因計算機而異。如何找到特定機器上的尾數長度?
我需要這個數字來執行數值分析的某些方面,比如分析錯誤。
我目前的想法是我可以編寫一個小的C++程序來緩慢增加一個數字,直到發生溢出,但我不確定使用什麼類型的數字。
我在正確的軌道上嗎?一個人究竟如何計算這個?
我會認爲你使用的任何語言將指定如何存儲浮動。我知道Java通過使用特定的IEEE標準來做到這一點(我認爲是754)。
如果沒有指定,我認爲你可以通過加0.5到1來做你自己的檢查,看看實際的數字是否改變。如果確實如此,那麼加0.25至1,0.125到1,依此類推,直到數量不發生變化,是這樣的:
float a = 1;
float b = 0.5;
int bits = 0;
while (a + b != a) {
bits = bits + 1;
b = b/2;
}
如果你只有3個尾數位,那麼1 + 1/16將等於1.
然後,你已經用盡了你的尾數位。
實際上您可能需要的基數是2而不是1,因爲IEEE754在開始時使用隱含的「1+」。
編輯:
它,因爲它給出63個比特爲清楚地具有4個字節的浮子系統出現上述可以具有一些問題的方法。
這是否是做與中間結果(I懷疑它因爲具有顯式轉換相同的代碼[while (((float)(a + b) != (float)(a))
]具有類似的問題)或(更可能的是,我相信)的單位值a
可以與更靠近位表示的可能性通過調整指數給分數b
,我還不知道。
現在,最好依靠上面提到的語言信息,如使用IEEE754(如果有這些信息)。
我會留下有問題的代碼作爲警惕球員的陷阱。也許有更多浮點知識的人,我可以留下一個說明,解釋它爲什麼奇怪地行爲(沒有猜想,請:-)。
編輯2:
這段代碼通過確保中間體被存儲在浮修復它。原來Jonathan Leffler是對的 - 這是中間結果。
#include <stdio.h>
#include <float.h>
int main(void) {
float a = 1;
float b = 0.5;
float c = a + b;
int bits = 1;
while (c != a) {
bits = bits + 1;
b = b/2;
c = a + b;
}
printf("%d\n",FLT_MANT_DIG);
printf("%d\n",bits);
return 0;
}
該代碼輸出(24,24),以顯示所計算的值相匹配的一個在頭文件。
雖然用C語言編寫,但它應該適用於任何語言(特別是信息在標題中不可用或憑藉它在語言文檔中指定的語言)。我只在C中測試過,因爲Eclipse需要很長時間才能啓動我的Ubuntu盒子:-)。
感謝您花費額外的時間來解決最初的問題 - 我瞭解您的邏輯,並且對於初始方式爲什麼沒有給出與FLT_MANT_DIG相同的答案也感到困惑。 – 2009-02-02 05:02:09
對於C和擴展C++,信息位於<float.h>
或<cfloat>
標頭中。
對於C99,該信息是在該標準的5.2.4.2.2節:
FLT_RADIX
FLT_MANT_DIG
FLT_DIG
FLT_EPSILON
FLT_MIN_EXP
FLT_MIN
FLT_MIN_10_EXP
FLT_MAX_EXP
FLT_MAX
FLT_MAX_10_EXP
同樣地,對於DBL和LDBL變體,大多數這些(無DBL_RADIX
或LDBL_RADIX
)。該標準提出了適用於IEEE 754(1999年出版的IEEE 754標準的舊版本;我相信2008年出版了新版本)的值。
使用Pax提出的方法得出63的答案,然而FLT_MANT_DIG表示他的尾數有23位數字。我想有些東西我不理解,但爲什麼差異? – 2009-02-02 03:29:14
你可能想看看在你的C++庫<limits>
:
#include <iostream>
#include <limits>
#include <typeinfo>
template <typename T>
void printDetailsFor() {
std::cout
<< "Printing details for " << typeid(T).name() << ":\n"
<< "\tradix: " << std::numeric_limits<T>::radix << "\n"
<< "\tradix digits: " << std::numeric_limits<T>::digits << "\n"
<< "\tepsilon: " << std::numeric_limits<T>::epsilon() << "\n"
<< std::endl;
}
int main() {
printDetailsFor<int>();
printDetailsFor<float>();
printDetailsFor<double>();
printDetailsFor<long double>();
return 0;
}
我認爲你要std::numeric_limits<T>::digits
這應該是比尾數位的數目多一個。我的機器打印出來了:
Printing details for i:
radix: 2
radix digits: 31
epsilon: 0
Printing details for f:
radix: 2
radix digits: 24
epsilon: 1.19209e-07
Printing details for d:
radix: 2
radix digits: 53
epsilon: 2.22045e-16
Printing details for e:
radix: 2
radix digits: 64
epsilon: 1.0842e-19
在某些系統上,模擬某些浮點類型(特別是那些沒有FPU的系統,當然)。 – strager 2009-02-02 02:24:24