关于底层Byte的一些用法

最近比较忙,所以,博客都有好几天没打理,这里给大家道一个谦!

现在是凌晨1:15分,有点晚了,太晚休息不利于健康,嗯,那一本《What can you do with bytes ?》的书,关于Byte的那一本,我读了还是觉得很不错,比较实用,结合计算机基础知识与Flash来讲。当然,对于那些对计算机基础(具体是数字逻辑那块)很扎实的同学,这一本书,或许你会认为它是在炒冷饭,但也请你也静下心来,看一看,温故而知新,若你能结合它提出你的新想法,请告诉我,作为一名CN IT 工作者,我为你感到骄傲!

\(^o^)/ I am Norris

早上11点04分:

先做一些小概念复习吧——
Byte是什么? #Byte其实是一个计算机存储信息大小的单位,翻译成中文,意思是字节,对,Byte就是字节,1kb =1024 b, b就是Byte,而1 Byte(字节) = 8 Bit(位),位就是Bit,具体单位转换请参看字节_百度百科

接下来,我们可以想想为什么要认识Byte?

#计算机的底层都是以Byte在传输数据,虽然我们不会说Byte国的语言,但我们有老朋友阿C、阿C++、阿汇编叔叔等为我们做翻译,所以我们在建造计算机王国时还是能轻松搭建起来,但是,如果你是认识Byte语言,是否会觉得少了翻译员在中间传话后,工作更快了? 所以,你要更牛B地构建你的计算机世界,你就得认识Byte。

小插曲:Byte有8个Bit,最大位放在最左边,最小位放在最右边. 从右到左渐渐变Big.Byte是二进制的,而我们日常生活用的最多的是十进制和六十进制,所以你还得学会如何转换进制,具体的转换方法,请参考这里

一些CPU运算会使用小端排序读取字节,而另一些则可能使用大端排序读取字节.所以,在发送数据到目标计算机前,先对Byte进行排序是十分有必要的,具体参考《What can you do with bytes ?》第一章12-13页。

另外,进行Byte运算,你必然少不了与按位运算符打交道(与、或、非、异或、移位)…

①在性能方面,使用移位来执行乘法或者除法运算会更加的高效(参考《What can you do with bytes ?》第一章第15页):
[cc lang="ActionScript"]var started:Number = getTimer();
var value:int = 8;
var result:int;
for ( var i:int = 0; i< 5000000; i++ )
result = value / 4;
// outputs : 2
trace( result );
//outputs : 617
trace( getTimer() - started );[/cc]

上面,我们进行了500万次除法运算,运算花费总时间为617毫秒。


[cc lang="ActionScript"]var started:Number = getTimer();
var value:int = 8;
var result:int;
for ( var i:int = 0; i< 5000000; i++ )
result = value >> 2;
// outputs : 2
trace( result );
//outputs : 586
trace( getTimer() – started );[/cc]

上面,我们使用了移位运算符,对于同样的运算量,结果最后的总花费时间为586毫秒,足足省下了31毫秒。

②在一些情况,我们可能需要优化空间以便尽可能多的了用空间。举个例子,一个含有8位的字节,在每一位中,0代表false,1代表true.Bit技术将允许我们在一个uint类型值中(32位)存储32种状态,而不用我们创建一个布尔值数组。使用这个技巧十分有利于数据传输。
下面我们创建了一个Bit的写入和读取的类方法:
[cc lang="ActionScript"]package com.norris2u4.byte
{
import flash.geom.Point;

/**
* @auther Norris
* @Date 2010年4月24日9:28:21
* 描述:该类主要实现了,字节中,Bit的写入和读取
*/
public class BitWriter
{
private var buffer :uint = 0; // 由位组成的位元组
public var length :uint = 0; // 移位的长度
private var pointer :uint = 0; // 虚拟指针位置,默认为最右边( 即0 )

public function writeBit(pBit:int):uint
{
/** 方法:向Buffer中写入一位Byte,默认从最右边开始 **/
// 若输入Byte小于0或者大于1,则抛出异常,否则返回成功写入Byte的新Buffer
if(0 > pBit || 1< pBit) throw new Error(" 参数必须为0或者1 ");
return buffer |= (pBit << (length = pointer++));
}

public function readBit():uint
{
/** 方法:从Buffer中读出一位Byte,默认从最右边开始 **/
// 若虚拟指针所指向的位置大于位元组的长度,则抛出异常,否则返回该位置的Byte
if(pointer > length) throw new Error(” 目标读取位置超出位元组的长度 “);
return uint( (buffer & (1 << pointer++)) != 0 ); // ?为什么与0做一个等价判断呢?
}

public function set position(pPosition:uint):void
{
/** 方法:设置虚拟指针的指向位置 **/
pointer = pPosition;
}

public function get position():uint
{
/** 方法:获取虚拟指针的指向位置 **/
return pointer;
}
}
}[/cc]

接下来,我们测试一下这个方法

[cc lang="ActionScript"]package
{
import com.norris2u4.byte.BitWriter;

import flash.display.Sprite;
import flash.events.Event;

public class Byte_Project extends Sprite
{
private var writer :BitWriter; // 读取位和写入位的方法类

public function Byte_Project()
{
// 如果舞台存在,则调用初始化函数init();
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init); // 监听器,实现舞台显示的初始化
}

/** 方法:实现舞台的初始化 **/
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init); // 删除舞台初始化的监听器
writer = new BitWriter(); // 实例化BitWriter()类
write(); // 写入位
read(); // 读取位
}

/** 方法:向位元组Buffer写入位Byte **/
private function write():void
{
// 输出 : 1
trace(writer.writeBit(1).toString(2));
// 输出 : 11
trace( writer.writeBit ( 1 ).toString ( 2 ) );
// 输出 : 111
trace( writer.writeBit ( 1 ).toString ( 2 ) );
// 输出 : 111
trace( writer.writeBit ( 0 ).toString ( 2 ) );
// 输出 : 10111
trace( writer.writeBit ( 1 ).toString ( 2 ) );
}

/** 方法:从位元组Buffer中读出位Byte **/
private function read():void
{
if(writer.position != 0) writer.position = 0;
for(var i:int=0; i <= writer.length; i++)
{
trace(writer.readBit());
}
}
}
}[/cc]
或许你现在可能还有疑惑,建这么一个方法,能不能说点实际的用途啊?

举个例子,在我们通过按钮来操控游戏时,若使用byte来控制按钮的状态(组合按钮,例如同时按下K+Y放一个大绝招),这将比设置多个Boolean值要来得方便,一个Byte就能判断了。一个uint类型有32Bit,对于键盘上26字母和一些Ctrl和Alt的功能键组合,我觉得足够了。
通过这个技术,我们就能仅仅用几个Bit,就能完全反应一个键盘上所有按键的状态。(Norris真是对Thibault Imbert无比的膜拜,十分有才的想法),具体例子参照Thibault Imbert博客(wiiflash.bytearray.org)上的WiiFlash游戏.

键盘按键的具体操作代码或者可以参考该书第一章(20页),-_-|||这是C#代码来的,不过,你把它当成伪代码看就是了…

暂时先写到20页的叙述先… (2010年4月24日11:36:23)

待续…

原创文章,转载请注明: 转载自Norris's Landscape

本文链接地址: 关于底层Byte的一些用法

2010-04-24   文章标签: , , , ,  | 当前有 3 个评论 »

3 Responses to “关于底层Byte的一些用法”

  1.  MorrisLiang wrote:

    哈,bytes是好东西,我blog就有个ico converter,用byteArray来实现ico的encode/decode。。

    四月 24th, 2010 at 10:02 上午
  2.  MorrisLiang wrote:

    实际上byte不一定就是最大位放在最左边,最小位放在最右边.要看Endian的。。

    四月 24th, 2010 at 9:37 下午
  3.  Norris wrote:

    这个是关于小端排序和大端排序的区分… 但大多数情况还是按照英特尔的模式执行(谁它这么普及)…

    四月 25th, 2010 at 11:26 上午

留下评论