文档章节

一个按比特位拷贝数据的函数copybits

乌合之众
 乌合之众
发布于 2015/06/17 11:09
字数 760
阅读 27
收藏 0

#一个按比特位拷贝数据的函数 没有进行特别的优化。其实还可以在拷贝源开始位置和目标开始位置是2的整数倍位置的时候进行优化。

##说明

这个函数用于从src数组首地址跳过sbb个字节,又跳过ssb个比特位,拷贝nbits个比特位的数据到dest数组首地址跳过dbb个字节,又跳过dsb个比特位位置。 copybits说明

##代码


include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

//二进制打印输出
void Bp(unsigned char n)  
{  
	int i;
	for (i=7;i>=0;i--)  
	{  
		printf("%u",(n>>i)&1);  
	}
}

//按比特位拷贝
// 从src数组首地址跳过sbb个字节,又跳过ssb个比特位,拷贝nbits个比特位的数据到
//   dest数组首地址跳过dbb个字节,又跳过dsb个比特位位置
int copybits(const unsigned char* src,int sbb/*source begin byte*/,int ssb/*source skip bit*/,
			unsigned char* dest,int dbb/*dest begin byte*/,int dsb/*dest skip bit*/,int nbits)
{
	// assert(src && dest && sbb>=0 && ssb>=0 && dbb>=0 && dsb>=0 && nbits>=0);
	if(src ==NULL || dest == NULL)return -1;
	if(sbb < 0 || ssb < 0 || dbb < 0 || dsb <0)return -2;
	if(nbits==0)return 0;
	
	if(ssb == dsb){
		//边界对其情况
		//1拷贝对齐部分
		int copybyte=(nbits -(8-ssb))/8;
		memmove(dest+dbb+1,src+sbb+1,copybyte);
		//2拷贝前端不完整字节
		if(ssb != 0){
			unsigned char s=src[sbb];
			s &= 0xFF>>ssb;
			dest[dbb] &= 0xFF<<(8-ssb);
			dest[dbb] |= s;
		}
		//拷贝后端不完整字节
		int endbit=(nbits - (8- ssb))%8;
		if(endbit != 0){
			unsigned char s=src[sbb+1+copybyte];
			s &= 0xFF<<(8-endbit);
			dest[dbb+1 + copybyte] &= 0xFF>>endbit;
			dest[dbb+1 + copybyte] |= s;	
		}
		return (8 - endbit);
	}
	//-------------------------------------------------
	
	int sbgb = sbb*8 + ssb;	//源开始的比特位置
	int dbgb = dbb*8 + dsb;	//目标开始比特位置
	int i,ret;
	int k1,m1,k2,m2;
	unsigned char s;
	if(((dest - src)*8+dbgb) < sbgb  ){
		// 目标开始位置在源开始位置左边
		for(i=0;i<nbits;++i){
			//拷贝某个位
			//1、源位置			目标位置
			k1=(sbgb+i)>>3;		k2=(dbgb+i)>>3;
			m1=(sbgb+i)&0x7;	m2=(dbgb+i)&0x7;
			s=src[k1];
			s &= 0x80>>m1;	//获取源比特位
			if(m1!=m2){	//偏移位
				s = m1<m2? (s>>(m2-m1)):(s<<(m1-m2));
			}
			dest[k2] &= (~(0x80>>m2));	//目标位置0
			dest[k2] |= s;	//目标位赋值
		}
	}
	else{
		for(i=nbits-1; i >=0 ;--i){
			//拷贝某个位
			//1、源位置			目标位置
			k1=(sbgb+i)>>3;		k2=(dbgb+i)>>3;
			m1=(sbgb+i)&0x7;	m2=(dbgb+i)&0x7;
			s=src[k1];
			s &= 0x80>>m1;	//获取源比特位
			if(m1!=m2){	//偏移位
				s = m1<m2? (s>>(m2-m1)):(s<<(m1-m2));
			}
			dest[k2] &= (~(0x80>>m2));	//目标位置0
			dest[k2] |= s;	//目标位赋值
		}

	}
	return (8 - (dbgb+nbits)%8);
}




int main()
{
	int i;
	unsigned char src[10]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};//{0,0x1F,0x0F,0x0F,0x70,0,0,1,1};
	unsigned char dst[10]={0,0,0,0,0,0,0,0,0};

	printf("%d\n",copybits(src,1,3,dst,0,5,24));

	for(i=0;i<10;++i){
		//printf("\t%2x\t%2x\n",src[i],dst[i]);
		Bp(src[i]);
		putchar(' ');
	}
	putchar('\n');
	for(i=0;i<10;++i){
		//printf("\t%2x\t%2x\n",src[i],dst[i]);
		Bp(dst[i]);
		putchar(' ');
	}
	putchar('\n');
	return 0;
}

© 著作权归作者所有

共有 人打赏支持
乌合之众
粉丝 13
博文 90
码字总数 79369
作品 2
海淀
程序员
同步、异步、阻塞和非阻塞的概念

在进行网络编程时,我们常常见到同步、异步、阻塞和非阻塞四种调用方式。这些方式彼此概念并不好理解。下面是我对这些术语的理解。 同步 所谓同步,就是在发出一个功能调用时,在没有得到结果...

AlphaJay
2010/06/03
0
2
读【深度探索C++对象模型】【中】

【构造和析构函数】 通常我们的看法是:当定义一个类的时候,如果没有为它写一个构造函数,系统将帮我们生成一个,并完成成员的初始化。但是,从编译器来看,上述看法中的两点认识都不够正确...

余二五
2017/11/14
0
0
ZIP文件格式详解

ZIP文件的总体格式 分文件头信息+文件压缩数据 中心目录+中心目录记录结束符 1.分文件头信息: 字节数 描述 4 分文件头信息标志(0x04034b50) 2 解压缩所需版本 2 通用比特标志位(置比特0位=加...

壶漏子
2015/10/09
1K
0
Linux 内核数据结构:位图(Bitmap)

本文由伯乐在线 -乔永琪 翻译,唐尤华 校稿。未经许可,禁止转载! 英文出处:0xAX。欢迎加入翻译组。 本系列: 《Linux 内核数据结构:Radix 树》 《Linux 内核数据结构:双向链表》 位图和...

伯乐在线
2016/12/10
0
0
Linux:信号(2):从内核看信号

想要有顺序地学习Linux,入口在这里哦:Linux:目录索引 一、信号在内核中的表示 二、可重入函数和不可重入函数 一、信号在内核中的表示 1.信号在内核中的三种状态 ①抵达态 执行信号的处理动...

w_y_x_y
05/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

MySQL数据库集群-PXC方案

网盘下载地址 MySQL数据库集群-PXC方案 PXC是开源的MySQL集群技术,如中国移动、阿里巴巴、腾讯、去哪网等企业均采用或者借鉴了PXC解决方案,可见该方案具有极佳的稳定性。本课程将在Linux环...

qq__2304636824
14分钟前
1
0
vue脚手架搭建项目

npm install -g vue-clivue init webpack my-projectcd my-projectnpm run dev

帝子兮
16分钟前
2
0
es6 字符串拓展方法

es6 include();返回Boolean,该字符串是否包含该字符 startWith() 返回Boolean,该字符串开头是否是该字符 endWith() 返回Boolean,该字符串结尾是否是该字符 repeat() 重复该字符串多少次,...

莫西摩西
17分钟前
1
0
Java语言实现word转PDF(10分钟解决)

前言: 经常做OA办公项目的同学一定和我一样被各种线上的office操作整疯了。基本上涉及到Java操作office的时候就会想到POI和openoffice.这两种方案都是需要找各种jar包,然后用里面繁杂的api。...

山里的红杏
18分钟前
1
0
Flask部分源码阅读

Flask主要依赖于Werkzeug和Jinja这两个库,是很简洁的Python Web框架。 Werkzeug 是一个WSGI的工具包,是Flask的核心库。 Jinja 则是一个模板渲染的库,主要负责渲染返回给客户端的html文件。...

Jian_Ming
22分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部