回 帖 发 新 帖 刷新版面

主题:二进制数据操作

2个数据,da1,da2,da1=11111111(255),da2=00000001(1),这2个数进行 异或运算(XOR),然后把运算结果da3右移1位,高位为0,判断右移出去的那位da4是0还是1?
da3=da1 XOR da2
da3=111111110(254)
da3右移da3=011111111(127)
da4=1
da1,da2,da3,da4,定义成那个数据类型。麻烦那位写下这个的VB代码,先谢了。

回复列表 (共11个回复)

沙发

都定义成字节型
要判断右移出去的d0位是1还是0,只要对da3(还没有右移的da3)进行奇偶验证,结果为偶数就是0,结果为奇数就是1。

板凳

[quote]都定义成字节型
要判断右移出去的d0位是1还是0,只要对da3(还没有右移的da3)进行奇偶验证,结果为偶数就是0,结果为奇数就是1。[/quote]
具体怎么做?字节是不是 BYTE, 这个不行,右移怎么移啊,VB代码怎么实现,1楼的朋友能写段代码吗,

3 楼

1、vb不擅长“位运算”。但仍可以做,就是效率低些。
2、建议,从你的现实问题出发,重新设计算法。
3、如你要坚持,代码如下:
Private Sub Command1_Click()
Dim da1 As Byte, da2 As Byte, da3 As Byte, da4 As Byte
da1 = 255
da2 = 1
da3 = da1 And da2'同为真
da3 = Not (da1 And da2)'同为假
da3 = da3 Or da4'或者同真,或者同假,这就是“异或”
da3 = da3 / 2'右移
da4 = 1'我不知道你的da4时怎么来的,就这样赋值了
Print da1, da2, da3, da4
End Sub

4 楼

[quote][quote]都定义成字节型
要判断右移出去的d0位是1还是0,只要对da3(还没有右移的da3)进行奇偶验证,结果为偶数就是0,结果为奇数就是1。[/quote]
具体怎么做?字节是不是 BYTE, 这个不行,右移怎么移啊,VB代码怎么实现,1楼的朋友能写段代码吗,[/quote]


右移除以2就行了,左移乘2,不过要取整,遇到奇数的时候,而且移出去的位要自己想办法,不是循环移位

5 楼

大喊三说得对:“右移除以2就行了”
代码如下:

Private Sub Command1_Click()
Dim da1 As Byte, da2 As Byte, da3 As Byte, da4 As Byte
da1 = 255
da2 = 1
da3 = da1 Xor da2
da4 = IIf(da3 / 2 = da3 \ 2, 0, 1) '能被2整除的是偶数
da3 = da3 \ 2                      '右移一位
Debug.Print da3, da4
End Sub

6 楼

用vb做位运算,不知意义何在?

7 楼

要判断右移出去的d0位是1还是0,也可以用逻辑运算来进行,更简单:
da4 = 1 and da3

8 楼

谢谢各位的回复,我改过几个程序,也做过几个控制程序,对VB也是刚入门很多的东西不懂,大部分需要的东西都是参考别人的程序的。
这是外单片系统的上位机软件,想用VB写,他的通信协议有个CRC的计算方法,我不知道怎么做,只能按表面的意思来做,具体的CRC算法如下所贴。
● CRC码的计算方法是: 
1.预置1个16位的寄存器为十六进制FFFF(即全为1);称此寄存器为CRC寄存器;
2.把第一个8位二进制数据(既通讯信息帧的第一个字节)与16位的CRC寄存器的低
   8位相异或,把结果放于CRC寄存器;
3.把CRC寄存器的内容右移一位(朝低位)用0填补最高位,并检查右移后的移出位;
4.如果移出位为0:重复第3步(再次右移一位);
如果移出位为1:CRC寄存器与多项式A001(1010 0000 0000 0001)进行异或;
5.重复步骤3和4,直到右移8次,这样整个8位数据全部进行了处理;
6.重复步骤2到步骤5,进行通讯信息帧下一个字节的处理;
7.将该通讯信息帧所有字节按上述步骤计算完成后,得到的16位CRC寄存器的高、低
   字节进行交换;
8.最后得到的CRC寄存器内容即为:CRC码。
我写了个比较繁的程序如下:

Dim a As Integer
Dim b As Integer
Dim c As Integer
Dim d As Integer
Dim e As Integer
Dim f As Integer
Dim g(7) As Byte
Dim h(7) As Byte
e = 255
f = 255
ttobi f, h()
neda:
b = InputBox("请输入0-255之间的数据,输入-1则结束本程序")
If b = -1 Then GoTo ends
e = e Xor b
ttobi e, g()
Dim i As Integer
Dim j As Integer

For j = 0 To 7
    a = g(0)
    For i = 0 To 6
        g(i) = g(i + 1)
    Next
    g(7) = h(0)
    For i = 0 To 6
        h(i) = h(i + 1)
    Next
    h(7) = 0
    If a = 1 Then
        e = g(7) * 2 ^ 7 + g(6) * 2 ^ 6 + g(5) * 2 ^ 5 + g(4) * 2 ^ 4 + g(3) * 2 ^ 3 + g(2) * 2 ^ 2 + g(1) * 2 + g(0)
        e = e Xor 1
        ttobi e, g()
        f = h(7) * 2 ^ 7 + h(6) * 2 ^ 6 + h(5) * 2 ^ 5 + h(4) * 2 ^ 4 + h(3) * 2 ^ 3 + h(2) * 2 ^ 2 + h(1) * 2 + h(0)
        f = f Xor 160
        ttobi f, h()
    End If
Label2.Caption = Str(h(7)) & Str(h(6)) & Str(h(5)) & Str(h(4)) & Str(h(3)) & Str(h(2)) & Str(h(1)) & Str(h(0)) & Str(g(7)) & Str(g(6)) & Str(g(5)) & Str(g(4)) & Str(g(3)) & Str(g(2)) & Str(g(1)) & Str(g(0))
Next
e = g(7) * 2 ^ 7 + g(6) * 2 ^ 6 + g(5) * 2 ^ 5 + g(4) * 2 ^ 4 + g(3) * 2 ^ 3 + g(2) * 2 ^ 2 + g(1) * 2 + g(0)
f = h(7) * 2 ^ 7 + h(6) * 2 ^ 6 + h(5) * 2 ^ 5 + h(4) * 2 ^ 4 + h(3) * 2 ^ 3 + h(2) * 2 ^ 2 + h(1) * 2 + h(0)
GoTo neda
ends:


'd = Right()
End Sub
其中Label2.Caption的目的就是验证结果,不知道是我理解错误还是程序错误,按上面的程序计算的结果根它提供的结果不同,举例如下:发送
01 10 00 00 00 0c 13 01 9b 00 32 00 32 00 50 00 32 00 90 01 3c 00 32 00 32 00 64 00 32 00
它提供的CRC是FC63,高手分析下。
如果用串口发送上面的数据怎么发,上面的是16进制的数,是不是把上面的数变成十进制的数再发送

9 楼

[quote]1、vb不擅长“位运算”。但仍可以做,就是效率低些。
2、建议,从你的现实问题出发,重新设计算法。
3、如你要坚持,代码如下:
Private Sub Command1_Click()
Dim da1 As Byte, da2 As Byte, da3 As Byte, da4 As Byte
da1 = 255
da2 = 1
da3 = da1 And da2'同为真
da3 = Not (da1 And da2)'同为假
da3 = da3 Or da4'或者同真,或者同假,这就是“异或”
da3 = da3 / 2'右移
da4 = 1'我不知道你的da4时怎么来的,就这样赋值了
Print da1, da2, da3, da4
End Sub
[/quote]
谢谢你的回复,异或用XOR就可以运算,上面的Da4是DA3右移出去的那位数。我上面赋值是根据上面的例子移出去的值赋的,在程序中是由右移出去的数赋值的。

10 楼

[quote]要判断右移出去的d0位是1还是0,也可以用逻辑运算来进行,更简单:
da4 = 1 and da3[/quote]
不能再加分的,看了半天明白你的意思,这确实是个好办法,是右移之前先判断,我试下运行结果。

我来回复

您尚未登录,请登录后再回复。点此登录或注册