一、基本概念
IEEE 754是由IEEE(電氣和電子工程師學會)制定的二進制浮點數算術標準,它定義了雙精度(double)、單精度(float)和擴展精度(extended)等多種浮點數格式,並規定了數值的編碼方式、最小規格值、舍入和異常處理等操作。
在計算機中,浮點數常用於表示非整數的實數(如π和根號2),由於實數集合無限大,因此需要尋求一種規律性的編碼方式,IEEE 754浮點數標準就是實現這一目的的標準。
二、浮點數表示
IEEE 754浮點數使用一位符號位、多位指數位和多位尾數位來表示一個實數,它的尾數是一個小數,其值的大小可以在不同的位數上進行改變。例如,單精度浮點數的符號位佔1位,指數位佔8位,尾數位佔23位。
//單精度浮點數的定義
typedef union {
float f;
struct {
unsigned int mantissa : 23;
unsigned int exponent : 8;
unsigned int sign : 1;
} parts;
} float_cast;
在上述代碼中,符號位sign佔用了最高位(最左邊),指數位exponent佔用了中間8位,尾數位mantissa佔用了最後23位。由於exponent佔用8位,其最大值為2^8-1=255,因此指數範圍為-126~127(實際指數還需減去127)。
三、舍入規則
在IEEE 754浮點數中,舍入有幾種不同的規則,包括向最近的偶數舍入、向0取整、向正無窮方向舍入和向負無窮方向舍入。容易想象,不同的舍入規則對於某些值而言,得到的結果會有所不同。
以單精度浮點數為例,下面的代碼演示了四種不同的舍入規則的實現:
//單精度浮點數的舍入方法
float round_to_nearest_even(float x) {
float y = round(x);
if (fabs(x - y) == 0.5) {
y = 2.0 * round(x / 2.0);
}
return y;
}
float round_toward_zero(float x) {
return (x > 0.0) ? floor(x) : ceil(x);
}
float round_up(float x) {
return ceil(x);
}
float round_down(float x) {
return floor(x);
}
四、溢出和下溢
當一個數字超出了浮點數所能表示的範圍時,就會發生溢出,它會被舍入為正無窮大或負無窮大。相反,當一個數字太小,無法被正確地表示時,就會發生下溢,它將被舍入為0。
在IEEE 754浮點數中,規定當指數大於最大可表示值時,為正無窮大,當指數小於最小可表示值時,為0,這就是浮點數溢出和下溢的表現。例如,對於單精度浮點數而言,最大值為3.4e38,最小值為1.2e-38。
五、異常處理
在計算機中,存在一些特殊情況,例如除以0、無限大加上無限小等,這些情況稱為異常或非數值(NaN)。IEEE 754浮點數標準規定了這些情況應該如何處理。
對於除以0,IEEE 754規定其結果應該是正無窮大或負無窮大,具體是哪一個由符號位sign指定;對於0除以0,應該得到未定義的結果(NaN);對於無限大減無限大,應該得到未定義的結果(NaN);對於不確定式(0/0、無限大/無限大或NaN/任何數值)的計算結果都是NaN。
//單精度浮點數的異常處理
float handle_exception(float x) {
if (x == 1.0 / 0.0) {
return 1.0;
} else if (x == -1.0 / 0.0) {
return -1.0;
} else if (x != x) {
return 0.0;
} else {
return x;
}
}
六、總結
IEEE 754浮點數標準提供了一種標準的方式來表示和處理浮點數,對於計算機科學領域而言非常重要。在編寫計算機程序時,需要了解這些標準,才能保證程序的正確性和可靠性。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/152716.html