Delphi 位运算符 shl shr or xor and not

理论知识来源:

1. https://blog.csdn.net/icewolf13/article/details/8330446?utm_source=blogxgwz8

2. https://www.cnblogs.com/guorongtao/p/12484872.html

做串口通讯的时候,经常用到CRC16校验,不同的设备厂家校验方法略有不同。

看着协议文档,是C++的校验代码,经常出现<< >> ^ &等位运算符号。

在网上查询了下,Delphi与C++位运算符的对应, 学习了下.

(地址是:)

位运算符对应关系如下

 C++  Delphi
&and
|or
取反~not
异或^xor
左移<<shl
右移>>shr

接下来是弄明白该符号的具体意思:

x shl nx的二进制数向左移n位,尾部补n个零(例子1)
x shr nx的二进制数向右移n位,首部补n个零(例子2)
x or n二进制(x 、n)相加,同1为1,有1则1 :1+1=1,0+1=1,0+0=0(例子3)
x xor n二进制(x 、n)相加, 同1为0,有1则1 :1+1=0,0+1=1,0+0=0(例子4)
x and n二进制(x 、n)相加,同1为1,有0则0 :1+1=1,0+1=0,0+0=0(例子5)
not x二进制取反(需先指定数据的大小),1为0,0为1(例子6)

例子1: 255 shl 2

      1. 255转化为二进制为: 1111 1111

      2. 该二进制数左移2位, 尾部补0,二进制变成: 11 1111 1100,转化十进制为1020

例子2: 255 shr 2

      1. 255转化为二进制为: 1111 1111

      2. 该二进制数右移2位, 首部补0,二进制变成: 0011 1111,转化十进制为63

例子3: 255 or 36

      1. 255转化为二进制为: 1111 1111

          36转化为二进制为  : 0010 0100 根据规则同1为1 有1则1 的规则进行转换

            转化后的二进制为 : 1111 1111 转化十进制为255

例子4: 255 xor 36

      1. 255转化为二进制为: 1111 1111

          36转化为二进制为  : 0010 0100 根据规则同1为0 有1则1 的规则进行转换

            转化后的二进制为 : 1101 1011 转化十进制为219

例子5: 255 xor 88

      1. 255转化为二进制为: 1111 1111

          88转化为二进制为  : 0101 1000 根据规则同1为1 有0则0 的规则进行转换

            转化后的二进制为 : 0101 1000 转化十进制为88

例子6: not 99

var
  iRet: Integer;
  iCal: Byte;
begin
  //需要指定数据的类型
  iCal:= 99;
  iRet:= not iCal;
  Memo1.Lines.Add(Format('运算结果: %u', [iRet]));
end;

      1. 99转化为二进制为: 0110 0011 根据规则1为0 0为1 的规则进行转换

          转化后的二进制为 : 1001 1100 转化十进制为156

      上面的iCal定义的是Byte类型,范围0..255, 取反为156, 如果定义Word类型, 取反为65436。

      所以,取反的值和iCal的定义类型有关。

实战效果:

      某公司的校验算法如下:

unsigned short CRC16(const unsigned char *buf, unsigned int len)
{
u16 crc = 0xaa;
    while(len--)
    {
        crc = (crc<<8) ^ crc16tab[((crc>>8) ^ *(unsigned char *)buf++)&0x00FF];
    }
    return crc;
}

转化为Delphi算法如下(其中crc16tab是个Word数组,就不粘贴了)

Function CRC16(ABuf:Tbytes): word;
var
  crc: Word;
  aByte: Byte;
  i, j: Integer;
begin
  crc:= $AA;
  for I := 0 to Length(ABuf) - 1 do
  begin
    crc:= (crc shl 8) xor crc16tab[((crc shr 8) xor Ord(ABuf[I])) and $FF];
  end;
  Result:= crc;  
end;

串口通讯校验通过,通讯正常。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值