- 浏览: 213627 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
strong8808:
activemq5.8.0 客户端,服务端启动序列图 -
xurichusheng:
第一题,如果使用 not exists 的话,可以改成:SEL ...
SQL笔试题 -
dingjun1:
cuisuqiang 写道如何解决呢?我的是对了也照样缓存增加 ...
事务未正确关闭引起的HIBERNATE SESSION不能正确关闭 -
dingjun1:
aijezdm915 写道lz ,我也是在写项目描述是犯愁,能 ...
如果在简历中描述项目 -
aijezdm915:
lz ,我也是在写项目描述是犯愁,能否给个你的简历demo,我 ...
如果在简历中描述项目
转帖:http://topic.csdn.net/t/20041019/00/3468250.html(snowingbf(snowingbf)2004-10-19 00:03:07 在 C/C++ / C++ 语言 提问)
有6种位运算:
& 与运算
| 或运算
^ 异或运算
~ 非运算(求补)
>> 右移运算
<< 左移运算
与运算(&)
双目运算。二个位都置位(等于1)时,结果等于1,其它的结果都等于0。
1 & 1 == 1
1 & 0 == 0
0 & 1 == 0
0 & 0 == 0
与运算的一个用途是检查指定位是否置位(等于1)。例如一个BYTE里有标识位,要检查第4位是否置位,代码如下:
BYTE b = 50;
if ( b & 0x10 )
cout << "Bit four is set" << endl;
else
cout << "Bit four is clear" << endl;
上述代码可表示为:
00110010 - b
& 00010000 - & 0x10
----------------------------
00010000 - result
可以看到第4位是置位了。
或运算( | )
双目运算。二个位只要有一个位置位,结果就等于1。二个位都为0时,结果为0。
1 | 1 == 1
1 | 0 == 1
0 | 1 == 1
0 | 0 == 0
与运算也可以用来检查置位。例如要检查某个值的第3位是否置位:
BYTE b = 50;
BYTE c = b | 0x04;
cout << "c = " << c << endl;
可表达为:
00110010 - b
| 00000100 - | 0x04
----------
00110110 - result
异或运算(^)
双目运算。二个位不相等时,结果为1,否则为0。
1 ^ 1 == 0
1 ^ 0 == 1
0 ^ 1 == 1
0 ^ 0 == 0
异或运算可用于位值翻转。例如将第3位与第4位的值翻转:
BYTE b = 50;
cout << "b = " << b << endl;
b = b ^ 0x18;
cout << "b = " << b << endl;
b = b ^ 0x18;
cout << "b = " << b << endl;
可表达为:
00110010 - b
^ 00011000 - ^0x18
----------
00101010 - result
00101010 - b
^ 00011000 - ^0x18
----------
00110010 - result
非运算(~)
单目运算。位值取反,置0为1,或置1为0。非运算的用途是将指定位清0,其余位置1。非运算与数值大小无关。例如将第1位和第2位清0,其余位置1:
BYTE b = ~0x03;
cout << "b = " << b << endl;
WORD w = ~0x03;
cout << "w = " << w << endl;
可表达为:
00000011 - 0x03
11111100 - ~0x03 b
0000000000000011 - 0x03
1111111111111100 - ~0x03 w
非运算和与运算结合,可以确保将指定为清0。如将第4位清0:
BYTE b = 50;
cout << "b = " << b << endl;
BYTE c = b & ~0x10;
cout << "c = " << c << endl;
可表达为:
00110010 - b
& 11101111 - ~0x10
----------
00100010 - result
移位运算(>> 与 <<)
将位值向一个方向移动指定的位数。右移 >> 算子从高位向低位移动,左移 << 算子从低位向高位移动。往往用位移来对齐位的排列(如MAKEWPARAM, HIWORD, LOWORD 宏的功能)。
BYTE b = 12;
cout << "b = " << b << endl;
BYTE c = b << 2;
cout << "c = " << c << endl;
c = b >> 2;
cout << "c = " << c << endl;
可表达为:
00001100 - b
00110000 - b << 2
00000011 - b >> 2
译注:以上示例都对,但举例用法未必恰当。请阅文末链接的文章,解释得较为清楚。
位域(Bit Field)
位操作中的一件有意义的事是位域。利用位域可以用BYTE, WORD或DWORD来创建最小化的数据结构。例如要保存日期数据,并尽可能减少内存占用,就可以声明这样的结构:
struct date_struct {
BYTE day : 5, // 1 to 31
month : 4, // 1 to 12
year : 14; // 0 to 9999
}date;
在结构中,日期数据占用最低5位,月份占用4位,年占用14位。这样整个日期数据只需占用23位,即3个字节。忽略第24位。如果用整数来表达各个域,整个结构要占用12个字节。
| 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 |
| | | |
+------------- year --------------+ month+-- day --+
现在分别看看在这个结构声明中发生了什么
首先看一下位域结构使用的数据类型。这里用的是BYTE。1个BYTE有8个位,编译器将分配1个BYTE的内存。如果结构内的数据超过8位,编译器就再分配1个BYTE,直到满足数据要求。如果用WORD或DWORD作结构的数据类型,编译器就分配一个完整的32位内存给结构。
其次看一下域声明。变量(day, month, year)名跟随一个冒号,冒号后是变量占用的位数。位域之间用逗号分隔,用分号结束。
使用了位域结构,就可以方便地象处理普通结构数据那样处理成员数据。尽管我们无法得到位域的地址,却可以使用结构地址。例如:
date.day = 12;
dateptr = &date;
dateptr->year = 1852;
============================================================================
负数的二进制表示方法
例如 -5
第一步:首先要把5变成101的二进制形式
第二步:再者就是安位取反,(形成前面全是1)010
第三步:在最后加1 形成:11111111 11111111 11111111 11111011
反过来如果把最高位是1的二进制变成负的整形时
第一步:位取反,变成00000000 00000000 00000000 00000100
第二步:在最低位加上1,形成101
第三步:形成整形5 ,在加上负号;
在二进制中,相反数的转变过程是这样的:先取反然后加1.
1.移位运算避免乘法
使用移位运算来避免乘法运算是一种常用技巧,不过乘数必须都是正整数,而且必须至少有一个是 2 的 n 次方,例如:2,4,8,16,32……移位运算的特点是速度快,而乘法运算速度较慢,把乘法运算转化为移位运算可以稍微提高程序运行效率。例如:
num *= 32;
等同于
num <<= 5; /* 2 的 5 次方等于 32 */
如果乘数不是 2 的 n 次方,我们可以把乘数分解成几个 2 的 n 次方的和:
num *= 20;
等于
num *= (16 + 4);
等于
num = num * 16 + num * 4;
等于
num = (num << 4) + (num << 2);
不过,现在的编译器很聪明,它们会代替我们做这种优化。也就是说,如果我们写的语句是:
num *= 100;
编译器会把这个语句优化为:
num = (num << 6) + (num << 5) + (num << 2);
所以,我们没有必要手工进行这种优化,因为编译器会替我们完成。而且,就算进行了这种优化,速度也不会有太大提高。我们应该把精力用来改进算法,一个好的算法可以让程序运行效率大大提高!
有6种位运算:
& 与运算
| 或运算
^ 异或运算
~ 非运算(求补)
>> 右移运算
<< 左移运算
与运算(&)
双目运算。二个位都置位(等于1)时,结果等于1,其它的结果都等于0。
1 & 1 == 1
1 & 0 == 0
0 & 1 == 0
0 & 0 == 0
与运算的一个用途是检查指定位是否置位(等于1)。例如一个BYTE里有标识位,要检查第4位是否置位,代码如下:
BYTE b = 50;
if ( b & 0x10 )
cout << "Bit four is set" << endl;
else
cout << "Bit four is clear" << endl;
上述代码可表示为:
00110010 - b
& 00010000 - & 0x10
----------------------------
00010000 - result
可以看到第4位是置位了。
或运算( | )
双目运算。二个位只要有一个位置位,结果就等于1。二个位都为0时,结果为0。
1 | 1 == 1
1 | 0 == 1
0 | 1 == 1
0 | 0 == 0
与运算也可以用来检查置位。例如要检查某个值的第3位是否置位:
BYTE b = 50;
BYTE c = b | 0x04;
cout << "c = " << c << endl;
可表达为:
00110010 - b
| 00000100 - | 0x04
----------
00110110 - result
异或运算(^)
双目运算。二个位不相等时,结果为1,否则为0。
1 ^ 1 == 0
1 ^ 0 == 1
0 ^ 1 == 1
0 ^ 0 == 0
异或运算可用于位值翻转。例如将第3位与第4位的值翻转:
BYTE b = 50;
cout << "b = " << b << endl;
b = b ^ 0x18;
cout << "b = " << b << endl;
b = b ^ 0x18;
cout << "b = " << b << endl;
可表达为:
00110010 - b
^ 00011000 - ^0x18
----------
00101010 - result
00101010 - b
^ 00011000 - ^0x18
----------
00110010 - result
非运算(~)
单目运算。位值取反,置0为1,或置1为0。非运算的用途是将指定位清0,其余位置1。非运算与数值大小无关。例如将第1位和第2位清0,其余位置1:
BYTE b = ~0x03;
cout << "b = " << b << endl;
WORD w = ~0x03;
cout << "w = " << w << endl;
可表达为:
00000011 - 0x03
11111100 - ~0x03 b
0000000000000011 - 0x03
1111111111111100 - ~0x03 w
非运算和与运算结合,可以确保将指定为清0。如将第4位清0:
BYTE b = 50;
cout << "b = " << b << endl;
BYTE c = b & ~0x10;
cout << "c = " << c << endl;
可表达为:
00110010 - b
& 11101111 - ~0x10
----------
00100010 - result
移位运算(>> 与 <<)
将位值向一个方向移动指定的位数。右移 >> 算子从高位向低位移动,左移 << 算子从低位向高位移动。往往用位移来对齐位的排列(如MAKEWPARAM, HIWORD, LOWORD 宏的功能)。
BYTE b = 12;
cout << "b = " << b << endl;
BYTE c = b << 2;
cout << "c = " << c << endl;
c = b >> 2;
cout << "c = " << c << endl;
可表达为:
00001100 - b
00110000 - b << 2
00000011 - b >> 2
译注:以上示例都对,但举例用法未必恰当。请阅文末链接的文章,解释得较为清楚。
位域(Bit Field)
位操作中的一件有意义的事是位域。利用位域可以用BYTE, WORD或DWORD来创建最小化的数据结构。例如要保存日期数据,并尽可能减少内存占用,就可以声明这样的结构:
struct date_struct {
BYTE day : 5, // 1 to 31
month : 4, // 1 to 12
year : 14; // 0 to 9999
}date;
在结构中,日期数据占用最低5位,月份占用4位,年占用14位。这样整个日期数据只需占用23位,即3个字节。忽略第24位。如果用整数来表达各个域,整个结构要占用12个字节。
| 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 |
| | | |
+------------- year --------------+ month+-- day --+
现在分别看看在这个结构声明中发生了什么
首先看一下位域结构使用的数据类型。这里用的是BYTE。1个BYTE有8个位,编译器将分配1个BYTE的内存。如果结构内的数据超过8位,编译器就再分配1个BYTE,直到满足数据要求。如果用WORD或DWORD作结构的数据类型,编译器就分配一个完整的32位内存给结构。
其次看一下域声明。变量(day, month, year)名跟随一个冒号,冒号后是变量占用的位数。位域之间用逗号分隔,用分号结束。
使用了位域结构,就可以方便地象处理普通结构数据那样处理成员数据。尽管我们无法得到位域的地址,却可以使用结构地址。例如:
date.day = 12;
dateptr = &date;
dateptr->year = 1852;
============================================================================
负数的二进制表示方法
例如 -5
第一步:首先要把5变成101的二进制形式
第二步:再者就是安位取反,(形成前面全是1)010
第三步:在最后加1 形成:11111111 11111111 11111111 11111011
反过来如果把最高位是1的二进制变成负的整形时
第一步:位取反,变成00000000 00000000 00000000 00000100
第二步:在最低位加上1,形成101
第三步:形成整形5 ,在加上负号;
在二进制中,相反数的转变过程是这样的:先取反然后加1.
1.移位运算避免乘法
使用移位运算来避免乘法运算是一种常用技巧,不过乘数必须都是正整数,而且必须至少有一个是 2 的 n 次方,例如:2,4,8,16,32……移位运算的特点是速度快,而乘法运算速度较慢,把乘法运算转化为移位运算可以稍微提高程序运行效率。例如:
num *= 32;
等同于
num <<= 5; /* 2 的 5 次方等于 32 */
如果乘数不是 2 的 n 次方,我们可以把乘数分解成几个 2 的 n 次方的和:
num *= 20;
等于
num *= (16 + 4);
等于
num = num * 16 + num * 4;
等于
num = (num << 4) + (num << 2);
不过,现在的编译器很聪明,它们会代替我们做这种优化。也就是说,如果我们写的语句是:
num *= 100;
编译器会把这个语句优化为:
num = (num << 6) + (num << 5) + (num << 2);
所以,我们没有必要手工进行这种优化,因为编译器会替我们完成。而且,就算进行了这种优化,速度也不会有太大提高。我们应该把精力用来改进算法,一个好的算法可以让程序运行效率大大提高!
发表评论
-
jstatd jsp 等不能正常运行的原因
2013-12-11 11:04 631[root@ bin]# ./jstatd Could not ... -
jvm信息查看
2013-06-03 08:28 7611、查看当前服务的cpu 、内存、磁盘等使用情况,看看是不是使 ... -
Paxos算法深入分析
2012-12-12 20:21 1052转载: http://blog.sina.com.cn/s/b ... -
Unveiling the java.lang.Out OfMemoryError
2011-04-13 19:02 907Unveiling the java.lang.Out OfM ... -
getOutputStream() has already been called for this response异常的原因和解决方法
2010-11-27 14:32 861getOutputStream() has already b ... -
servlet filter url-pattern
2010-10-28 09:47 1300ApplicationFilterFactory: /** ... -
JVM内存
2010-09-26 16:03 1017转载:http://blog.csdn.net/c ... -
java nio 笔记
2010-08-19 20:16 1976一、基础知识 操作系统 ... -
集合框架
2010-08-04 22:09 864集合框架: BitSet:??? Ha ... -
基本数据结构介绍
2010-08-01 18:22 940二叉查找树: 性质:设x为二叉查找树中的一个结点。如果y是x的 ... -
理解弱引用(Understanding Weak References)转
2010-07-31 12:58 1231转载:http://blog.csdn.net/x ... -
设置SESSION超时时间
2010-07-02 15:07 1469设置session时间的3个方法: 1. 在tomcat--c ... -
垃圾收集机制
2010-04-23 16:49 812转载:http://tech.ccidnet.com/art ... -
JAVA语言细节总结
2010-04-17 12:47 8641、java 源代码文件通常称为一个编译单元,每个编译单元内最 ... -
utf8的编码原理
2009-07-20 15:08 1155大概意思: 在UTF8中,字符使用1到6个八位序列编码。 只有 ... -
转发(forward)、包含(include)及转向(redirect)的区别与联系
2009-07-17 15:57 979转发(forward)、包含(include)及转向(redi ... -
对数运算公式
2009-07-03 16:15 2156附件二为自然对数的介绍PPT -
二叉树相关知识
2009-07-03 16:04 943一、二叉树的构建与打印 Node.java publ ... -
ThreadLocal的几种误区
2009-06-26 10:48 836转载:http://www.blogjava.ne ... -
JAR打包
2009-03-13 15:38 999在CMD下,当我们敲下jar -help时,系统给我们提供了如 ...
相关推荐
在C#中,位运算符有六种:位逻辑非运算、位逻辑与运算、位逻辑或运算、位逻辑异或运算、位左移运算和位右移运算。 1. 位逻辑非运算 位逻辑非运算是单目的,只有一个运算对象。位逻辑非运算按位对运算对象的值进行...
使用位运算计算LOG2 LOG2是数学中一个常用的函数,用于计算一个数字的对数。然而,在计算机科学中,我们更关心的是如何使用位运算来计算LOG2。位运算是一种快速且高效的运算方法,可以用于加速很多复杂的操作。下面...
正在学习位运算的人群
位运算在计算机科学中扮演着重要的角色,尤其是在底层系统编程和硬件交互时。位运算符允许程序员直接操作数据的二进制位,从而实现高效的数据处理和计算。本文将详细介绍位运算符,位运算,以及位段的概念。 首先,...
位运算在Java编程中是底层操作,用于直接处理二进制数据,对于理解计算机内部机制和优化代码性能至关重要。本文将深入探讨位运算的相关知识,包括计算机中数据的表示方法、二进制计数系统、以及原码、反码和补码的...
本软件集合了位运算跟进制的转换,简单操作,方便软件工程人员使用,同时也适用于初学c语言的大学生,大学教师使用。
其中,“&”表示按位与运算,“|”表示按位或运算,“^”表示按位异或运算,“~”表示按位取反运算,“”表示左移运算,“>>”表示右移运算。 #### 四、各种位运算的具体使用 ##### 1. And 运算 (按位与运算) - *...
【转载】常用位操作 位运算应用口诀 常用位操作 几个常用的位操作 计算树状数组lowbit的三种方法 统计一个整数的二进制中1的个数(位运算技巧) 收藏 统计一个整数的二进制中1的个数的三种方法 位运算讲稿_by_...
位运算是一种在计算机科学中广泛使用的操作,它直接作用于数据的二进制位上,是计算机底层操作的重要部分。位运算在嵌入式开发、系统编程、算法优化等领域具有重要应用。以下是对位运算的详细说明: 1. **位运算的...
快速位运算算法优化 位运算是计算机科学中一种基本操作,广泛应用于数字信号处理、图形处理、密码学等领域。快速位运算算法可以提高计算效率,降低计算时间。本文总结了各种快速位运算算法,涵盖了位运算的基础知识...
### C++位运算详解 在计算机科学中,位运算是一种直接对整数的二进制表示进行操作的运算。它们通常用于低级别的编程任务,如硬件接口、数据压缩、密码学以及性能关键型应用程序中。C++作为一种强大的编程语言,提供...
位运算在编程中是一种高效的运算方式,特别是在处理底层数据和优化算法时,具有重要的作用。本文将详细解析位运算的概念、运算符、应用以及注意事项。 首先,位运算是基于二进制位的操作,它直接对数据的二进制表示...
位运算及其相关技巧在程序设计的应用 位运算是一种在计算机科学和编程中广泛使用的操作,它直接作用于整数在内存中的二进制表示。这种运算不仅速度快,而且在许多场景下能够提供简洁高效的解决方案。本文将深入探讨...
C语言位运算 有6种: &, | , ^(亦或), <<(左移), >>(右移)。 注意:参与位运算的元素必须是int型或者char型,以补码形式出现。 按位与& &运算常应用于: 迅速清零 保留指定位 判断奇偶性 a & 1 = 1...
位运算练习题参考答案 本文档提供了一系列位运算练习题的参考答案,涵盖了位运算的基本概念、运算符优先级、位运算符的使用、掩码的应用、移位运算等知识点。 1. 位运算符优先级 在 C 语言中,位运算符的优先级从...
c语言位运算c语言位运算c语言位运算c语言位运算c语言位运算
### C中的位运算详解 #### 一、位运算概述 位运算是计算机程序设计中一个重要的概念,它涉及对数据的二进制位进行直接操作。由于数据在计算机内部是以二进制形式存储的,因此通过位运算可以直接访问并修改这些二...
### 基于位运算的两种字符串加密解密算法 #### 一、位运算概述及特点 位运算是一种直接在二进制位上进行的操作,主要用于处理数据的底层细节。在计算机科学领域,特别是操作系统、计算机网络协议以及软件设计等...