文档章节

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

乌合之众
 乌合之众
发布于 2015/06/17 11:09
字数 760
阅读 25
收藏 0
点赞 0
评论 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
ZIP文件格式详解

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

壶漏子
2015/10/09
1K
0
读【深度探索C++对象模型】【中】

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

余二五
2017/11/14
0
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
常用的加密算法

概述 加密算法分为单向加密和双向加密,明文数据通过加密后传输,以确保传输和存储安全 单向加密包括 MD5、SHA、BCrypt 加密算法等,它是不可逆的,也就是无法将加密后的数据恢复成原始数据,...

林塬
2017/12/25
0
0
反向投影图

本次要讲的范例是反向投影,反向投影如果是按照字面上的理解,还有书本上的理解可能会比较困难,但是如果是举一些具体的简单的例子,那可能就比较容易接受了,应用的话,可以检测出肤色区域,...

元禛慎独
2016/10/18
4
0
OpenGL位图和图像

  在前面的章节中,已经讲述了几何数据(点、线、多边形)绘制的有关方法,但OpenGL还有另外两种重要的数据类:一是位图,二是图像。这两种数据都是以象素矩阵形式存储,即用一个矩形数组来...

teacheryang
2010/11/19
0
0
bitmap 和布隆过滤器

如何解决排重问题: 对于大量的数据,有很多排重方案可以使用,典型的就是哈希表。哈希表实际上为每一个可能出现的数字提供了一个一一映射的关系,每个元素都相当于有了自己的独享的一份空间...

与你咫尺天涯
03/03
0
0
Java数据类型之byte和char

1 bit = 1 个二进制位 1 byte = 8 bit 基本数据类型 Java基本数据类型 int 32bit short 16bit long 64bit byte 8bit char 16bit float 32bit double 64bit 位(bit) 比特(英语:Bit),亦称......

秋风醉了
2014/05/15
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Spring Boot Admin 2.0开箱体验

概述 在我之前的 《Spring Boot应用监控实战》 一文中,讲述了如何利用 Spring Boot Admin 1.5.X 版本来可视化地监控 Spring Boot 应用。说时迟,那时快,现在 Spring Boot Admin 都更新到 ...

CodeSheep
16分钟前
0
0
Python + Selenium + Chrome 使用代理 auth 的用户名密码授权

米扑代理,全球领导的代理品牌,专注代理行业近十年,提供开放、私密、独享代理,并可免费试用 米扑代理官网:https://proxy.mimvp.com 本文示例,是结合米扑代理的私密、独享、开放代理,专...

sunboy2050
58分钟前
0
0
实现异步有哪些方法

有哪些方法可以实现异步呢? 方式一:java 线程池 示例: @Test public final void test_ThreadPool() throws InterruptedException { ScheduledThreadPoolExecutor scheduledThre......

黄威
今天
1
0
linux服务器修改mtu值优化cpu

一、jumbo frames 相关 1、什么是jumbo frames Jumbo frames 是指比标准Ethernet Frames长的frame,即比1518/1522 bit大的frames,Jumbo frame的大小是每个设备厂商规定的,不属于IEEE标准;...

六库科技
今天
0
0
牛客网刷题

1. 二维数组中的查找(难度:易) 题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入...

大不了敲一辈子代码
今天
0
0
linux系统的任务计划、服务管理

linux任务计划cron 在linux下,有时候要在我们不在的时候执行一项命令,或启动一个脚本,可以使用任务计划cron功能。 任务计划要用crontab命令完成 选项: -u 指定某个用户,不加-u表示当前用...

黄昏残影
昨天
0
0
设计模式:单例模式

单例模式的定义是确保某个类在任何情况下都只有一个实例,并且需要提供一个全局的访问点供调用者访问该实例的一种模式。 实现以上模式基于以下必须遵守的两点: 1.构造方法私有化 2.提供一个...

人觉非常君
昨天
0
0
《Linux Perf Master》Edition 0.4 发布

在线阅读:https://riboseyim.gitbook.io/perf 在线阅读:https://www.gitbook.com/book/riboseyim/linux-perf-master/details 百度网盘【pdf、mobi、ePub】:https://pan.baidu.com/s/1C20T......

RiboseYim
昨天
1
0
conda 换源

https://mirrors.tuna.tsinghua.edu.cn/help/anaconda/ conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/conda config --add channels https://mir......

阿豪boy
昨天
1
0
Confluence 6 安装补丁类文件

Atlassian 支持或者 Atlassian 缺陷修复小组可能针对有一些关键问题会提供补丁来解决这些问题,但是这些问题还没有放到下一个更新版本中。这些问题将会使用 Class 类文件同时在官方 Jira bug...

honeymose
昨天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部