我们编程都离不开二进制数,因为计算机存储数据是以二进制的形式存储的,而且用指定的二进制数位保存数据,可以节约内存。举个简单的例子:当我们定义个int型变量,存储一个0-255的数,是不是都会觉得浪费内存,答案肯定是的,存储一个0-255的数,我们都会毫不犹豫地选择unsigned char类型。大家看到这个例子都会觉得你说的什么意思,根本没解释用二进制数位保存数据可以解决内存。
别急,再举个例子:大家听说过RGB888和RGB565吧?不过相信部分同学是没听过的,RGB888就是用3个字节保存一个像素的颜色,一个字节8位,用高8位代表红色(R),中间8位代表绿色(G),低8位代表蓝色(B),RGB888一般用在计算机上;而RGB565一般用在嵌入式平台上,既节约内存,也解决硬件条件的缺陷,RGB565就是用2个字节保存一个像素的颜色,
用高5位代表红色(R),中间6位代表绿色(G),低5位代表蓝色(B),其实完全可以把5位/6位的数据用一个字节的内存来存,存成3个字节,如果这样做的话,在嵌入式平台将耗费太多的存储空间,本来存储空间就有限,一个像素就多一个字节,以一张分辨率为800*600的图片为例,就是多800*600个字节,要是有100张这样的图片,就多了800*600*100=48000000B=46MB;了解硬件的都只知道,现在用的比较多的NAND Flash常规的才是128MB,48MB的话,无缘无故要从128MB的空间腾出48MB。
其实上面说的都不是我在项目中遇到的问题,我在项目中遇到的问题是要将RGB55的R5位和B5位交换存储位置,当时赶着下班,而且刚好用0x001F这个颜色值做测试,心里也清楚,就是把0x001F变成0xF100就可以了,当时一头热赶着下班,直接将这个数的二进制位逆置就完了,刚好由于选的是0x001F这个颜色值,逆置后现象就对了,就以为解决问题了。
后面想了想才发现那样做肯定是不对的,正确的做法是先把高5位R和低5位B提出来,再把提出来的高5位R放到低5位,把提出来的低5位B放到高5位,思路有了,编写程序也就简单了,就是进行&和|的操作,具体代码如下:
-
unsigned short exchangeRGB565(unsigned short srcRGB)
-
{
-
unsigned short desBGR;//定义desBGR用来保存交换后的结果
-
unsigned short RGB_R = 0;//用来保存提取出来的R5位
-
unsigned short RGB_B = 0;//用来保存提取出来的B5位
-
RGB_R = (srcRGB&0x001F)<<11;//提取B5位,并移到到高5位
-
RGB_B = (srcRGB&0xF800)>>11;//提取R5位,并移到到低5位
-
desBGR = srcRGB&0x07e0;//清除高5位和低5位数据
-
desBGR |= RGB_R;//R5位放到低5位
-
desBGR |= RGB_B;//B5位放到高5位
-
return desBGR;
-
}
总结一下二进制位中的&和|操作的作用:
①0xYYYY & 0x001F操作的话,就是获取低5位的数据,清除高11位的数据;
②0xYYYY | 0x001F操作的话,就是将0xYYYY低5位的数据修改为1F,高11位不变。
这也是单片机配置寄存器的值经常这样干的,先进行&0操作,清除指定位,再|操作,配置指定数据。
前面提到二进制数据的逆序,其实方法很多,我这里就说一种吧,其实说白了,就是将最高位和最低位交换,以此类推,我下面实现的方法是需要通过加入一个中间变量,每次保存原二进制数的最低位,再左移1位,代码如下:
-
#include<stdio.h>
-
#include<stdlib.h>
-
int main()
-
{
-
int n = 0;
-
int num =0;
-
int i = 0;
-
scanf("%d", &n);
-
for (i = 0; i < 32; i++)
-
{
-
num = num << 1; //当num的最低位保存了数据之后再左移
-
num |= ((n>>i)&1); //将n的第i个bit位与num按位或,将这一位保存到num中
-
}
-
printf( "n=%d num=%d\n", n,num);
-
system( "pause");
-
return 0;
-
}
阅读(1791) | 评论(0) | 转发(0) |