6

我必须实现校验和(CRC16 CCITT)来验证文件的内容。由于 << 和 >> 运算符以及网上提供的许多示例,校验和在 C 或 Java 中实现起来相当简单。

问题是……我的校验和计算必须在 VBScript 中实现。

我对这种语言的体验几乎为零,但据我了解,没有任何东西可以在 VBScript 中进行位移。因此,我依赖于乘法和除以二。它工作得很好,除了负值

我进行了一些测试,我相信 VBScript 用二进制补码处理它的 16 位整数。

Q1:有人可以证实我这一点(VBScript 中的二进制补码)吗?我没有从 MSDN 网站上找到任何准确的信息。

Q2:当负数用二进制补码编码时,是否可以通过简单的数学运算进行位移(左右)?

.

非常感谢,我真的很想避免像处理整数作为'1'和'0'的数组或从VBScript调用一些java / c应用程序这样的混乱。

编辑感谢您的帮助,在下面找到我在 VBScript 中右移的实现:

Function rightShift(value,bits)
    Dim res

    res = 65535 AND value

    If value>=0 Then
       res = res \ (2^bits)
    Else If value=-1 Then
             res = rightShift(res + 32768, bits - 1)
         Else
             res = rightShift(value \ 2 + 32768, bits - 1)
         End If
    End If

    rightShift = res AND 65535
End Function 

请注意上面的代码:值有时会超过 16 位,因此我必须屏蔽未使用的位以避免溢出 ( AND 65535)。

4

3 回答 3

5

在二进制补码算术中,负值的唯一影响是除以 2 右移:预期的右移将发生,但它也会在最高有效位 (MSB) 位置引入一个新的 1 位“保持负值”——除非原始值为 -1,在这种情况下所有位都变为 0。因此,要纠正这一点,请尝试以下伪代码:

rightshift(x) {
    if x >= 0 return x / 2;
    if x < -1 return x / 2 - MINVAL;    # Strip out sign bit
    # x must be -1, i.e. "all bits on"
    return x - MINVAL;
}

MINVAL应该是其表示仅由 MSB 开启和所有其他位关闭的值,对于 16 位,它是 -32768。(之所以这样命名,是因为它将是使用二进制补码的最负数可表示的数字。)有趣的是,MINVAL在上述伪代码中,加法和减法一样有效,因为在二进制补码算术中,x - y=x + NOT(y) + 1MINVAL == NOT(MINVAL) + 1.

使用乘以 2 的左移对负数的作用与对正数的作用一样。

于 2012-04-30T04:13:40.013 回答
0

这不是回答,而是评论。@j_random_hacker 给出的答案对我有用。但是在像 C# 这样执行整数除法的语言中(假设您出于某种原因不能使用内置的右移运算符),当 x 不是偶数时,需要四舍五入。

static int MINVAL = (int) -0x80000000;
    static int ShiftRight(int n,int bits)
    {
        //if (n >= 0) return n / (int)Math.Pow(2, bits);
        //double temp = n / Math.Pow(2, bits);
        //int r  = (int) Math.Floor(temp);
        //return r;
        if (n >= 0) return n / 2;
        if (n < -1) return (int)Math.Round(n / (double)2, MidpointRounding.AwayFromZero) - MINVAL;//+ (n%2==0?0:-1);    // Strip out sign bit
        // x must be -1, i.e. "all bits on"
        return n - MINVAL;
    }

现在是的,C# 有一个内置的移位运算符,所以这只是教育目的。

于 2014-03-17T06:33:22.013 回答
-1

太慢了,试试这个。以下适用于值> = 0,但对于位移> 14位将抛出一个数组下标超出范围,代码为:

dim ShiftArray
ShiftArray = Array(1, 2, 4, 8, 16, 32, 64, 128, 256, 512,
1024,2048,4096, 8192, 16384)

' example usage
dim num
num = 17
num = num * ShiftArray(2) ' left shift 2 bits
num = num / ShiftArray(3) ' right shift 3 bits

乘以要左移的位数。除以右移。该数组适用于 16 位整数。

对于 32 位整数,对于位移 > 30,数组将超出范围数组下标,并且是:

dim ShiftArray
ShiftArray = Array(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024,   
2048,4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288,
1048576, 2097152, 4194304, 8388608, 16777216, 33554432,
67108864, 134217728, 268435456,  536870912, 1073741824)
于 2015-08-24T16:41:50.530 回答