2009-04-27 89 views
8

我正在基于Velleman k8055开发板的一个小硬件接口项目上工作。为什么AND两个数字要得到一个布尔值?

示例代码来在VB.Net,我重写这个到C#,主要是为了有机会步执行代码,使这一切的感觉。

有一件事我百思不得其解,但:

在一个阶段,他们阅读所有数字输入,然后设置一个复选框基于答案读取数字输入(该回来的整数),然后他们和这有一个数字:

i = ReadAllDigital 
cbi(1).Checked = (i And 1) 
cbi(2).Checked = (i And 2) \ 2 
cbi(3).Checked = (i And 4) \ 4 
cbi(4).Checked = (i And 8) \ 8 
cbi(5).Checked = (i And 16) \ 16 

我还没有在一段时间做数字系统,我知道他们正在尝试做的,但它必须和两个数字有什么影响? 0以上的所有内容都不等于真实吗?

你会如何翻译这为C#?

+0

感谢您的所有答案...我从来没有机会在过去做任何Bitwise的东西...嗯,我想我不能再说了。 ;-) – Gineer 2009-05-01 09:51:00

回答

15

我想你会需要它翻译成这样:

i & 1 == 1 

i & 2 == 2 

i & 4 == 4 

等等 这是使用按位与运营商。

当您使用位AND运算符,这样操作人员比较两个给定的值的二进制表示,并返回只有那些位设置一个二进制值,这也是在两个操作数设置。

例如,当你这样做:

它会做到这一点:

0010 & 0010 

,这将导致:

0010 
0010 
&---- 
0010 

然后,如果你将这个结果与2(0010)进行比较,它就会返回true。

19

这是做bitwise AND,不是逻辑和。

每个那些的基本决定是否在i单个位被设置,例如:

5 AND 4 = 4 
5 AND 2 = 0 
5 AND 1 = 1 

(因为5 =二进制101,和图4,2和1是二进制100的十进制值,010和001分别。)在二进制例如

+0

5 AND 4 = 4,当然,这就是为什么问题说(5 AND 4)\ 4 – MSalters 2009-04-27 10:02:47

1

想到这

10101010 

AND 

00000010 

产生00000010

即不为零。现在,如果第一个值是

10101000 

你会得到

00000000 

即为零。

注意进一步分化的一切减少到1或0。

1

(i和16)/ 16提取第5位的值(1或0)。

1xxxx and 16 = 16/16 = 1 
0xxxx and 16 = 0/16 = 0 
1

And运算符执行“...两个数字表达式的按位数连接”,映射到“|”在C#中。 “”是integer division,如果两个操作数都是整数类型,则C#中的等效值为/

1

常数是masks(以二进制形式考虑它们)。所以代码的作用是在字节和掩码上应用bitwise AND运算符并除以数字,以获得该位。

例如:

xxxxxxxx & 00000100 = 00000x000 
if x == 1 
    00000x00/00000100 = 000000001 
else if x == 0 
    00000x00/00000100 = 000000000 
1

如所述,这是一个按位AND,而不是一个逻辑AND。我确实看到这在我之前已经说过很多次了,但海事组织的解释并不那么容易理解。

我喜欢把它像这样:

写了二进制数下对方(我在这里做5和1):

101 
001 

现在我们需要把它变成二进制数,所有从第1号1成的,这也是第二个被转移,那就是 - 在这种情况下:

001 

在这种情况下,我们看到它给出了相同数量作为第二数字,我这个操作(在VB中)返回true。让我们来看看另一个例子(使用5,因为我):

(5和2)

101 
010 
---- 
000 

(假)

(5和4)

101 
100 
--- 
100 

(真)

(5和8)

0101 
1000 
---- 
0000 

(假)

(5和16)

00101 
10000 
----- 
00000 

(假)

编辑:显然我错过了问题的整个点 - 这里的翻译,以C#:

cbi[1].Checked = i & 1 == 1; 
cbi[2].Checked = i & 2 == 2; 
cbi[3].Checked = i & 4 == 4; 
cbi[4].Checked = i & 8 == 8; 
cbi[5].Checked = i & 16 == 16; 
3

只需添加: 它被称为位掩码 http://en.wikipedia.org/wiki/Mask_(computing)

一个布尔值只需要1位。在大多数编程语言的实现中,布尔值需要多于一个位。在个人电脑上这不会是一个大的浪费,但是嵌入式系统通常存储空间非常有限,所以浪费非常重要。 为了节省空间,布尔值被打包在一起,这样布尔变量只占用1位。

你可以把它看作是做这样的事情的数组索引操作,随着越来越像8个布尔变量数组的字节(= 8位),所以也许这就是你的答案:使用布尔值数组。

1

在C#中使用BitArray class来直接索引各个位。

若要设置单个位很简单:

b |= 1 << i; 

要复位单个位是多了几分尴尬:

b &= ~(1 << i); 

要知道,无论是位运算符换班经营者倾向于将所有事情推广到int,这可能意外需要施放。

1

我比较喜欢在旋转位时使用十六进制符号(例如0x10而不是16)。它更有意义,因为您增加您的位深度为0x20000比131072更好。

相关问题