存储单个位
回答
这很可能是通过组合不同的二进制标志来完成。为了能够给你一个清晰的解释,你必须了解数字如何按位表示。基本上,它就像十进制数字一样,只有两个数字可用。下面是一个例子(二进制表示中的十进制数字0-16)。
Decimal Binary
0 0
1 1
2 10
3 11
4 100
5 101
6 110
7 111
8 1000
9 1001
10 1010
11 1011
12 1100
13 1101
14 1110
15 1111
16 10000
这正是您的电脑如何存储数字。 你还必须得到一个关于按位运算符的基本认识。 假设你有8位的两行看起来是这样的:
10101010
01011111
如果您在使用逐位或操作结合这两个行 - “|” - 输出的比特x是1,如果其中第1行的位x是1或第2排的位x为1。因此,在我们的情况下,结果是这样的:
11111111
按位与运算符( &)检查两排1的比特x是1,行2的比特x是1。 在我们的这种情况下是输出:
00001010
的逐位XOR(异或)运算符(^)检查是否我们的输出如下:
11110101
基本上Minecraft的开发者所做的是他们定义了几个标志。
// this is just an example, not Minecraft's actual code
public static final byte ORIENTATION_SOUTH = 0; // 00000000
public static final byte ORIENTATION_NORTH = 1; // 00000001
public static final byte ORIENTATION_WEST = 2; // 00000010
public static final byte ORIENTATION_EAST = 3; // 00000011
public static final byte PART_UPPER = 4; // 00000100 - third bit is 1
public static final byte PART_LOWER = 0; // 00000000 - third bit is 0
public static final byte STATE_OPEN = 8; // 00001000 - fourth bit is 1
public static fianl byte STATE_CLOSED = 0; // 00000000 - fourth bit is 0
所以,如果他们想在门的上部朝西,是一个车门开着状态,他们会写这样的:
byte state = ORIENTATION_WEST | PART_UPPER | STATE_OPEN;
位明智的,它应该是这样的:
00000010 | (orientation)
00000100 | (part)
00001000 (open or closed)
,然后这些最终成为:
00001110 (west, upper part, open)
虽然只有字节的前4位被使用,正如你所说的,你不能只保存位。最有可能的是整个字节被保存。
定义:
DOOR_UP = 0x01
DOOR_LEFT = 0x02
DOOR_BIG = 0x04
DOOR_SMALL = 0x08
DOOR_RED = 0x10
DOOR_BLUE = 0x20
DOOR_GREEN = 0x40
如果你需要离开,小,绿色的门写
def door := DOOR_LEFT or DOOR_SMALL or DOOR_GREEN (Z** or some generic language)
byte door = DOOR_LEFT | DOOR_SMALL | DOOR_GREEN; (C++)
是检查门绿色 “问”:
door & DOOR_GREEN
零表示不绿色。非零(实际上,DOOR_GREEN)是指绿色的门
增加:
你甚至可以包0-7两个数字中的一个字节。同样的想法是在ZX频谱(1982)用来定义字符的颜色:
Xbbbfff (bbb - background color, fff - foreground color, X - for blink)
要设置BKG色5和FGD 4使用:
color = 5 << 3 | 4
要获得背景色用途:
(color >> 3) & mask(0x7) -> 5
如果你每制作一个游戏都很重要。尽量避免使用位操作,只要你可以:)
你是对的,当你需要的只是存储一个位时,你不能这样做:你必须至少保存一个字节。
但是,如果您有多个项目,每个项目占用少于一个字节,您可以将多个项目组合在一个字节中。
以4位门为例,假设您要存储两扇门的信息。你需要8位,这是一个字节。您可以将第一个门保存在较低的四位中,第二个门保存在较高的四位中。当您需要获得第一个门的状态时,通过应用twoDoorsInOneByte & 0x0F
操作屏蔽掉第二个门:它删除字节的较高部分。当你需要第二扇门时,使用左移位移位:(twoDoorsInOneByte >> 4) & 0x0F
:它将高四位移动到高四位,并且清除字节上半部分的位,以防你的值感叹 - 延长。
最后,在C中你有另一种选择:你可以使用bit fields。如果您想将任意长度的元素打包成几个字以节省空间,这可能很有用。请注意,当节省相对较高或存储器太细时(例如,您正在为8位微控制器编写嵌入式代码)时,应谨慎应用此技术。
尽管他们说他们使用4位,但我知道他们实际上是将信息存储在一个字节中(这很容易创建,因为字节是一种基本数据类型)。
我不认为有可能直接存储一个位,但我想你想知道,尽管他们声称他们使用4位,但这些位存储在一个字节中。
几乎所有的现代计算机都是字节可寻址的,这意味着您只能寻址(指向)一个字节的内存并且不会更小。所以在这种情况下,他们正在存储一个字节。为了让在钻头他们关心他们使用位操作来操纵字节:
const int OPEN_CLOSE_BIT = 1 << 0;
const int UPPER_LOWER_BIT = 1 << 1;
byte doorByte = getByteFromSomewhere();
if (doorByte & UPPER_LOWER_BIT) {
// the door is in some state
}
- 1. 存储多个位 - 我应该使用多个列还是单个位域列?
- 2. MySQL以毫秒为单位存储TIMESTAMP
- 3. 在SQL中存储值和单位
- 4. PYTHONPATH存储位置
- 5. AS3位图存储
- 6. 多个SVN存储库或单个公司存储库
- 7. 显示DICOM单色2,其位数少于存储位数
- 8. 单个与多个Linq2sql存储库
- 9. 多个用户的单个存储库
- 10. IntelliJ创意中缓存和索引的单独存储位置
- 11. 一个Mercurial存储库能否位于另一个Mercurial存储库中?
- 12. PHP Cookie存储用户表单搜索 - 存储多个搜索
- 13. 将两个x86 32位寄存器存储到128位xmm寄存器中
- 14. Windows Mobile和存储位置
- 15. boost :: dynamic_bitset如何存储位
- 16. Android:Usb存储位置在3.0?
- 17. Android - 访问存储位置
- 18. Boost.Interprocess中存储器位置
- 19. 在Android中存储位图
- 20. 存储目录位置
- 21. 存储网格位置
- 22. 虚表的存储位置
- 23. svn +存储库位置
- 24. 图像存储位置
- 25. 存储Google位置SQLite中的位置
- 26. 存储器 - AVAIL位VS PRESENT位
- 27. 从单个转储文件加载多个svn存储库
- 28. 上传单个图像到firebase存储
- 29. 如何在salesforce中存储单个值
- 30. 多个存储库,单一设置
它是通过bitpacking完成的,将各种信息放入单个字节的数据中。 – Alastair 2012-02-05 02:02:19
http://en.wikipedia.org/wiki/Bitwise_operation – 2012-02-05 02:06:04