C++用位运算输出变量的二进制序列

题目要求如下:

C++用位运算输出变量的二进制序列_第1张图片

 

 

分析binaryOut这个函数:

       unsigned char tmp = 0x80,转换为二进制就是1000,0000。而字符c在内存中所占大小为一字节,与1000,0000做按位与运算其实就取决于字符c的ascii码转换为二进制的首位是1还是0。

        如'a',其ascii码为97,转换为二进制就是0110,0001,与1000,0000按位与就得到0。而0作为判断条件即为假,输出了0;接着tmp>>=1,即tmp右移一位,得到0100,0000,与a(0110,0001)按位与得到1,为真,输出1…… 以此类推,即输出了'a'的二进制序列。

 

    注:这里如果用tmp的类型能不能是char而不是unsigned char?

 

        需要注意char是带符号的,因此其范围是-128~127,若赋值1000,0000(128)则会溢出,且会变为-128(1000,0000的第一位是1,代表了是负数)。

分析displayInBinary这个函数:

        这里面有两个参数,其中void *data是无类型指针,它指向的数据类型暂时不确定;后期使用时一般要通过强制类型转换(再转换成具体类型前不能通过*解引用,因为void指针只知道指向变量的首地址,而不知道指向变量所占的字节大小)。而int  len参数就是变量所占字节的大小。

 

第一种实现方法:

#include 
using namespace std;

void displayInBinary(void *data , int len);
void binaryOut(char c);


int main(){
	char c = 'a';
	short n = 257;
	float f = 1.0f;
	
	displayInBinary(&c,sizeof(c));
	displayInBinary(&n,sizeof(n));
	displayInBinary(&f,sizeof(f));
	
	return 0;

}



void displayInBinary(void *data , int len){
	int move = 8*(len-1);			
	unsigned int tmp = 0x80<>=1; 

    } 
    cout <<"\n";

}

    这里我的想法是根据变量所占的字节数,来取得不同的tmp与其做位运算。比如short是2位,我就用1000,0000,0000,0000和它做按位与运算。

    输出结果如下:  

 

01100001
0000000100000001
00111111100000000000000000000000

 

 

关于打印浮点数的疑惑:

 

 

    为什么这里可以用int型指针指向存放float型的地址?是否会发生类型转换呢?

        个人认为这里将data的地址强制转为int型的地址是没有什么区别的,因为地址就是地址:

	//float f = 1.0f;
        cout << data << endl;
	cout << (int *)data << endl;
	cout << *(int *)data << endl;

    输出结果如下:

0x71ff2c
0x71ff2c
1065353216

    其中1065353216转换为二进制就是00111111,10000000,00000000,00000000。

 

为什么是这样的呢?

    

    这里就要说说浮点数的存储方式了:

        根据国际标准IEEE规定,任何一个浮点数NUM的二进制数可以写为: 

        NUM = (-1)^S*M*2^E;

        ①当S(sign)为0时,表示一个正数;当S为1时,表示一个负数 。

        ②E(exponent)表示指数:即科学计数法中的指数,2的多少次方。

        ③M(mantissa)表示尾数部分。

C++用位运算输出变量的二进制序列_第2张图片

        因此00111111,10000000,00000000,00000000可以解读为0,01111111,00000000000000000000000。

        其中M(尾数)部分看上去只有23位的精度,事实上是有24位:因为科学计数法中,如1.01001*2^5,事实上小数点前的1是可以省略的。

        然而E(指数)部分看上去有8位,实际上只有7位的精度,因为指数是有正负的。因此指数其实是从00000000(-127)开始到11111111(+128)结束的。故这里的01111111应该解读为指数为0。从而浮点数f的值就是1.0了。

 

 

 

第二种实现方法:

    (是老师给出的思路)

#include 
using namespace std;

void binaryOut(char);
void displayInBinary(void *, int);

int main(){
	char c = 'a';
	short n = 100;
	float f = 1.0f;
	
	displayInBinary(&c,sizeof(c));
	displayInBinary(&n,sizeof(n));
	displayInBinary(&f,sizeof(f));
	
	return 0;
}


   
void binaryOut(char c){    

	unsigned char tmp=0x80; 

    for(int i=0; i<8; i++){
        if(c&tmp) 
            cout << 1; 
        else 
            cout << 0; 
        tmp >>=1; 
    }
}

void displayInBinary(void * data, int len){
	char *ptr = (char *)data;
	ptr += (len-1);          
	//栈中高地址往低处增长,先让指针指向高地址
	//才能按顺序打印出来
	
	for(int i =0; i

 

其中对于 ptr += (len-1); 我们需要分析一下栈中的存储情况:

 

(以short n=100为例)

C++用位运算输出变量的二进制序列_第3张图片

 

    因此在for循环中ptr--就是将指针向低地址方向移动;从而借助binarOut函数将其二进制序列打印出来。

你可能感兴趣的:(C++用位运算输出变量的二进制序列)