C语言基础

    返回首页    发表留言
本文作者:李德强
          第六节 浮点型位运算
 
 

        今天我们来一起看看浮点数的位运算。其实,早在前面的内容中我们已经讲过,浮点数是不能进行位运算的,也就是说float型变量和double型变量都不能做位运算。原因是浮点型变量在内存中的存储方式与整型变量不同,以float型为例,它占用4个字节的内也就是32个bit位,最高位用于存放符号位0表示正数,1表示负数。而后的8个bit位表示其阶码,即2的-128次方到2的127次方,再后续的低23个bit位表示其尾数,由高到低分别表示2的-n次方。所以对于这样的浮点数表示法是不能做位移运算的,因为一旦对浮点数做位移运算,其符号位阶码和尾数就会发生很大的变化,所以编译器会禁止编程都对浮点型变量做位运算。

        但是我们可以利用一些特殊办法对浮点数做位运算操作。下面介绍两种下可以对浮点数做位运算的方法:利用共用体或指针


一、利用共用体


        在前一节中我们学习了共用体的定义与使用,我们知道共用体中的属性都是共享同一块内存区域,所以我们可以利用共用体中的整型变量对与其共用同一内存区域的浮点型变量做位运算。例如我们可以定义这样一个共用体:

 

typedef union
{
	int i;
	float f;
} u;

u val;

val.i = 13;
printf("i = %d\n", val.i);

val.f = 13.5;
printf("f = %f\n", val.f);


i = 13 
f = 13.500000

 


        其中int i与float f被定义成一个共用体的两个属性,所以它们占用同一块内存区域,我们可以通过修改i的值来达到修改值的目的,例如:

 

u val;
val.f = 13.5;
printf("f = %f\n", val.f);

//将i的最高位置成1
val.i |= (1 << 31);
printf("f = %f\n", val.f);

f = 13.500000
f = -13.500000


        这样我们就通过位运算将f变量的符号位由0修改成了1,f的值也就由正数变为了负数。我们再来看下面一个例子:

 

u val;

val.f = 0.0f;
printf("f = %f\n", val.f);

val.i |= (1 << 31);
val.i |= (0x45 << 24);
val.i |= 0x76E979;

printf("f = %f\n", val.f);


f = 0.000000 
f = -3950.592041

 


        最初f的值为0,我们可以通过对i的位运算来对其值进行修改。我们分别将i的各个位的值修改成1,于是f的符号位为1表示负数,阶码为1000101表示133-127为6,尾数为11101101110100101111001所以根据浮点数的定义浮点数的值应该为-3950.592041。当然这个浮点数的有效位数只有7位最后的041其实是无效数字。


二、利用指针


        其实利用指针来对浮点数做位与算与利用共用体的办法很类似。我们可以使用一个整型指针来指向一个浮点型变量,这样再对整弄指向的内存地址做位运算,例如:

 

float f = 123.598765;
int *p =  (int *)&f;
printf("0x%X\n", *p);

0x42F73291


        我们定义了一个int *p表示一个整型指针,并使其指向浮点型变量float f。当然在为其赋值时需要使用(int *)对&f也就是f的地址做强制类型转换。这样我们就让一个整型指针指向了一个浮点型变量,于是我们就可以对指针所指向的变量做位移运算了。


        注意浮点型变量本身是不能做位移运算的,但对于指针p来说,编译器认为这是一个整型变量的地址,于是就允许其做位移运算。关于使用指针来对浮点型变量做位移运算的程序我们不再赘述,这与使用共用体的方法类似,请读者自己思考并动手编写程序。


三、注意安全


        其实我们对浮点数做位运算本身就影响到程序的安全性,因为浮点型变量的存储方式与普通整型变量完全不同。例如整型变量左移1位,其值变为原来的2倍,右移1位,其值变为原来的一半。而对于浮点型变量来说,如果对其向左或向右位移1位,其符号位、阶码、尾数都会发生变化,其最终结果是不可直观预料到的。所以,出于这样的考虑,编译器才会禁止对浮点型变量的位运算。其实,本节内容的主要目的是为了让读者了解共用体、指针的原理与使用方法,以及浮点型变量的存储方式,而在实际编程的过程中并不提倡对浮点型变量做位运算。


 

    返回首页    返回顶部
  看不清?点击刷新

 

  Copyright © 2015-2023 问渠网 辽ICP备15013245号