算法習題---3.12浮點數(UVa11809)
阿新 • • 發佈:2019-05-06
所有 out 範圍 open style con 32位 保存 stdin
一:題目
尷尬的非會員水印
二:題目摘要
1.int和float比較
int共32位,可以表示的最大的數為2^32次方 float雖然也是32位,但是是以指數形式保存,指數占8位(含符號),最大127,則表示最大數為2^127,可以表示到10^38次方數
2.float在內存中存在形式
其中尾數部分,默認前面省略了一個1
3.輸入數據的範圍
9.205357638345294e18 5.699141892149156e76 -->不能單純用float表示 0e0
double類型指數占11位,最高可以表示到10^308次方,可以滿足輸入條件
三:解題思路
(一)整數部分除2,小數部分乘2
例如:19.625
整數
19/2 = 9...1 9/2=4...1 4/2=2...0 2/2=1...0 1/2=0...1
19 = 10011
小數
0.625*2 = 1.25 --> 1 0.25*2 = 0.5 --> 0 0.5*2 = 1.0 --> 1
0.625 = 0.101
(二)位數確定(2^10=1024)>10^3>(2^9=512)
Xe18位數範圍為18/3*9到(18/3+1)*10之間--->其中18/3+1中+1是為了防止X帶來的誤差(例如X=8就是2^3,所以我們不妨直接將其擴大10位,即1*10)
(三)函數pow的參數是double類型,返回也是double類型
(四)為了在處理小數時方便計算,將double類型轉float(兩種保留位數不同,float位數較少)
四:數據展示
9.205357638345294e18 5.699141892149156e76 0e0
8 6 5 8
五:代碼分析
(一)獲取指數值
bit = 0; while (temp>1) { temp /= 10; bit++; } bit--; //bit是整數位數(1000.1就是bit=3)
for (bin_bit = bit / 3 * 9; bin_bit <= (bit / 3 + 1) * 10; bin_bit++)
{
if ((num / pow(2.0, bin_bit)) < 1)
break;
}
其中num是我們獲取的需要處理的最大浮點數
bin_bit是根據三(二)中確定的值,循環次數從bit/3*9到(bit/3+1)*9,
當num/pow(2.0,bin_bit)小於1時,就是處理了所有的的指數值
(二)根據指數值,獲取尾數值
//指數是bin_bit位 //尾數是num / pow(2.0, bin_bit) mant_val = num / pow(2.0, bin_bit); //double轉float只是為了保留15位小數,方便後面比較運算 expo_val = bin_bit;
(三)根據三(一)獲取指數值位數
while (expo_val)
{
expo++; //初始為0
expo_val /= 2;
}
(四)根據小數運算獲取小數位數
while (mant_val>1e-15) //因為float有效位數15位
{
if (mant_val * 2 >= 1.0)
mant_val = mant_val*2 - 1;
else
mant_val = mant_val * 2;
mant++;
}
mant--; //因為有一個1被默認省略,所以減去
六:代碼實現
//浮點數求尾數和指數位數 //整數部分除2,小數部分乘2 void test37() { double num, temp; //考慮位數,取double類型 int bit,bin_bit; float mant_val; //尾數值 int expo_val; //指數值 int mant, expo; //尾數位數和指數位數 freopen("data.in", "r", stdin); freopen("data.out", "w", stdout); while (1) { scanf("%lf", &num); //註意:double類型讀取時,使用lf expo = mant = 0; temp = num; if (temp == 0) break; bit = 0; while (temp>1) { temp /= 10; bit++; } bit--; for (bin_bit = bit / 3 * 9; bin_bit <= (bit / 3 + 1) * 10; bin_bit++) { if ((num / pow(2.0, bin_bit)) < 1) break; } //指數是bin_bit位 //尾數是num / pow(2.0, bin_bit) mant_val = num / pow(2.0, bin_bit); //double轉float只是為了保留15位小數,方便後面比較運算 expo_val = bin_bit; while (expo_val) { expo++; expo_val /= 2; } while (mant_val>1e-15) { if (mant_val * 2 >= 1.0) mant_val = mant_val*2 - 1; else mant_val = mant_val * 2; mant++; } mant--; //因為有一個1被默認省略,所以減去 printf("%d %d\n", mant, expo); } freopen("CON", "r", stdin); freopen("CON", "w", stdout); }
算法習題---3.12浮點數(UVa11809)