算法习题---3.12浮点数(UVa11809)

it2022-05-05  167

一:题目

尴尬的非会员水印

二:题目摘要

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); }

 

转载于:https://www.cnblogs.com/ssyfj/p/10818380.html


最新回复(0)