位操作也疯狂
来源:互联网 发布:百度 霸屏 js 代码 编辑:程序博客网 时间:2024/05/05 15:44
在ActionScript中,对数值的某些位操作可以显著提高运算效率,下面就与大家分享我工作中常用的和不常用的以及刚学习到的一些位操作知识。
1.字节与位
1个字节(byte)=8个二进制位(bitwise)
2.有符号整数和无符号整数
我们知道在计算机里面,以二进制存储着一个数值,在这个二进制数中最左边的一位一般用来表示正数还是负数。0表示正数,1表示负数。一个8位无符号整数的取值范围是0~2^8-1(2的8次方减1),而一个8位有符号整数的取值范围是-2^7~2^7-1,因为最左边1位是作为标示位来标示正数还是负数,有效计算大小的只是后面的7位。
3.按位和按位组合赋值
- & (bitwise AND)将expression1和expression2转换为 32 位无符号整数,并对整数参数的每一位执行布尔 AND 运算。
- | (bitwise OR)将expression1和expression2转换为 32 位无符号整数,并在expression1或expression2的对应位为 1 的每个位的位置上放置 1。
- ~ (bitwise NOT)将expression转换为一个 32 位带符号整数,然后按位对 1 求补。
- ^ (bitwise XOR)将expression1和expression2转换为 32 位无符号整数,并在expression1或expression2中对应位为 1(但不是在两者中均为 1)的每个位的位置上放置 1。
- << (bitwise left shift)将expression1和shiftCount转换为 32 位整数,并将expression1中的所有位向左移动由shiftCount转换所得到的整数指定的位数。
- >> (bitwise right shift)将expression和shiftCount转换为 32 位整数,并将expression中的所有位向右移动由shiftCount转换所得到的整数指定的位数。
- >>> (bitwise unsigned right shift)此运算符与按位向右移位运算符 (>>) 基本相同,只是此运算符不保留原始表达式的符号,因为左侧的位始终用 0 填充。
(注意:as3中没有<<<)
- &= (bitwise AND assignment)对expression1赋予expression1& expression2的值。
- |= (bitwise OR assignment)对expression1赋予expression1 / expression2的值。
- ^= (bitwise XOR assignment)对expression1赋予expression1 ^ expression2的值。
- <<= (bitwise left shift and assignment)执行按位向左移位 (<<=) 运算,并将内容作为结果存储在expression1中。
- >>= (bitwise right shift and assignment)执行按位向右移位运算,并将结果存储在expression中。
- >>>= (bitwise unsigned right shift and assignment)执行无符号按位向右移位运算,并将结果存储在expression中。
4. &操作
1
var
a:
int
=
13
;
2
var
b:
int
=
11
;
3
trace
(a & b);
//9
A.判断奇偶
依据:偶数的二进制末尾是0,与1进行按位与,结果为0.奇数的二进制末尾是1,与1进行按位与,结果为1.
1
//判断奇偶
2
var
a:
int
=
int
(Math.random() *
1000
);
3
if
(a &
1
){
4
trace
(a +
"是奇数"
);
5
}
else
{
6
trace
(a +
"是偶数"
);
7
}
B.快速取模运算
当a%b,b是2^n的时候,可以写成a&(2^n-1)
- a % 8
- a&7
- a%16
- a&15
- a%256
- a&255
5.|操作
1
var
a:
int
=
13
;
2
var
b:
int
=
11
;
3
trace
(a | b);
//15
关于&与|在程序设计中有个妙用,就是用来判断是否具备某个属性,以及用来生成一条记录,满足若干属性。
这一点我举个例子说明:
写个很简单的c语言例子,以前写的顺便黏贴了过来:
01
#include <stdio.h>
02
03
int
main()
04
{
05
unsigned
int
i;
06
unsigned
int
boy = 0x1;
07
unsigned
int
girl = 0x2;
08
09
unsigned
int
music = 0x4;
10
unsigned
int
game = 0x8;
11
unsigned
int
travel = 0x16;
12
unsigned
int
read = 0x32;
13
14
//逻辑或:用于记录生成男孩+游戏+旅行
15
unsigned
int
test2 = boy | game | travel;
16
//逻辑或:用于记录生成女孩+音乐+旅行
17
unsigned
int
test = girl | music | travel;
18
19
//逻辑与:判断是否满足某种条件
20
if
(test & boy == boy){
21
printf
(
"test is a boy\n"
);
22
}
else
{
23
printf
(
"test is a girl\n"
);
24
}
25
if
(test & music == music){
26
printf
(
"test loves music\n"
);
27
}
else
{
28
printf
(
"test doesn't love music\n"
);
29
}
30
31
if
((test & girl == girl) && (test & game != game)){
32
printf
(
"test is a girl and she doesn't love game.\n"
);
33
}
34
getchar
();
35
}
通常的做法是把一些互相排斥没有交集的一些属性定义为2^n,
如1、2、4、8或者写成0x1、0x2、0x4、0x8或者1<<0、1<<1、1<<2、1<<3等,
1
var
a:
int
=
1
<<
0
;
//var a:int = 1;
2
var
b:
int
=
1
<<
1
;
//var b:int = 2;
3
var
c:
int
=
1
<<
2
;
//var c:int = 4;
4
var
d:
int
=
1
<<
3
;
//var d:int = 8;
关于&|的用法,这里只是抛砖引玉,相信你们有更妙的用法~~~
6. << 和 >>
A.倍数问题
1
a *
2
== a <<
1
;
2
a *
4
== a <<
2
;
3
a *
8
== a <<
3
;
4
a *
16
== a <<
4
;
5
a *
32
== a <<
5
;
1
a /
2
== a >>
1
;
2
a /
4
== a >>
2
;
3
a /
8
== a >>
3
;
4
a /
16
== a >>
4
;
5
a /
32
== a >>
5
;
1
3.14159
>>
0
==
3
;
2
3.14159
<<
0
==
3
;
C.颜色的相关操作
- 颜色的生成:
01
//产生随机颜色
02
var
r:
int
=Math.round(Math.random()*
255
);
03
var
g:
int
=Math.round(Math.random()*
255
);
04
var
b:
int
=Math.round(Math.random()*
255
);
05
trace
(r +
","
+ g +
","
+ b)
06
var
col:
Number
= r <<
16
| g <<
8
| b;
//通过按位操作,获取颜色值
07
//创建显示对象
08
var
sp:Sprite=
new
Sprite();
09
sp.graphics.beginFill(col);
10
sp.graphics.drawCircle(
60
,
60
,
50
);
11
sp.graphics.endFill();
12
addChild(sp);
我们随便给一个颜色值,比如1个24位颜色值,用16进制表示,随便取个吧,如0x342388,那么很显然红色字节表示的大小是34(16进制中的34),绿色字节表示的大小是23,蓝色字节表示的大小是88,我们可以把0x342388理解成0x340000 | 0x002300 | 0x000088。我们解析下上面那段程序:
1
var
r:
int
=Math.round(Math.random()*
255
);
2
var
g:
int
=Math.round(Math.random()*
255
);
3
var
b:
int
=Math.round(Math.random()*
255
);
r = 34;
g = 23;
b = 88;
而通过这3个数值组成一个颜色值,需要r的二进制向左移动16位,r << 16, g的二进制向左移动8位,而b的二进制则不需要移位操作。
那32位颜色的合成和24位基本相同,只是多了透明度:
1
var
alpha:
uint
=
0x22
;
2
var
r:
uint
=
0x34
;
3
var
g:
uint
=
0x23
;
4
var
b:
uint
=
0x88
;
5
var
color:
uint
= alpha <<
24
| r <<
16
| g <<
8
| b;
- 颜色的分解
现在我们知道了rgb的16进制值,那反过来呢?如果我们知道了一个颜色值,如何反向求解rgb值呢?
1
var
color:
uint
=
0x342388
;
2
var
r:
uint
= color >>
16
;
//右移16位,把2388移出,取0x34
3
var
g:
uint
= color >>
8
&
0xff
;
//右移8位,把88移出,得0x3423,与0xff按位与操作,得0x23
4
var
b:
uint
= color &
0xff
;
//得到0x88<span></span>
1
var
color:
uint
=
0xff342388
;
2
var
a:
uint
= color >>>
24
//注意这里是>>>,无符号右移位操作,右移24位,把342388移出,得到0xff
3
var
r:
uint
= color >>
16
&
0xff
;
//右移16位,把2388移出,取0x34
4
var
g:
uint
= color >>
8
&
0xff
;
//右移8位,把88移出,得0x3423,与0xff按位与操作,得0x23
5
var
b:
uint
= color &
0xff
;
//得到0x88
7.>>>无符号右移位操作
as3中没有<<<无符号左移位操作符,那>>>与>>的区别在哪???
我们举个例子:比如一个透明度为1的一个黑色,用16进制表示的32位颜色为0xff000000,那其实二进制是
1111 1111 0000 0000 0000 0000 0000 0000 color
1111 1111 1111 1111 1111 1111 1111 1111 color >>24结果
0000 0000 0000 0000 0000 0000 1111 1111 color >>>24结果
对比可以发现:
- >>:当color的最高有效位(最左端的位)为 0 时,左侧的位都填补 0;如果最高有效位为 1,左侧的位都填补 1。
- >>>:此运算符与按位向右移位运算符(>>)基本相同,只是>>>不保留原始表达式的符号,因为左侧的位始终用 0 填充。
- 这就是下行代码为何用>>>的原因
1
var
a:
uint
= color >>>
24
//注意这里是>>>,无符号右移位操作,右移24位,把342388移出,得到0xff
8.~和^
A. 取绝对值
(x ^ (x >> 31)) – (x >> 31);B.交换数值
1
var
k:
int
= a;
2
a = b;
3
b = k;
4
/*等价于*/
5
a ^= b;
6
b ^= a;
7
a ^= b;
- 按位异或:11为0,10为1,00为0。那么同一个数对另一个数进行2次按位抑或,仍然是本身。
如果有错误欢迎朋友指出,转载请注明出处:http://my.oschina.net/game007
- 位操作也疯狂
- Window也疯狂
- 家庭宽带也疯狂
- VC 界面也疯狂
- Loading 也疯狂
- Jerry 也疯狂...
- 服装业:虚拟也疯狂
- 动物也疯狂
- NULL也疯狂
- 银行也疯狂!!!
- 丑女也疯狂
- template 模板也疯狂
- android模拟器也疯狂
- orz也疯狂
- BURG 引导也疯狂
- github也疯狂
- 学生也疯狂
- A+B也疯狂
- Android Touch事件传递机制解析(一)
- 多个个框架静态编译是注意的一点Build Active Architecture Only
- websphere性能调优方案
- Sqlite命令操作
- LINQ to SQL语句之Insert/Update/Delete操作
- 位操作也疯狂
- 配置FREEGLUT(新)
- mysql error number 2003错误告诉你怎么回事
- 基于自定义JS框架的UI库之自定义框架
- 关于C/C++中表达式求值顺序的深层次问题
- android 获取屏幕的分辨率
- GNS3 ASA 多模式 contexts mode multiple 设置
- 预习AJAX1
- 澳大利亚投票拓展-阿罗的不可能定理