一:题目
尴尬的非会员水印
二:题目摘要
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