6

ファイルの内容を確認するためにチェックサム(CRC16 CCITT)を実装する必要があります。チェックサムは、<<および>>演算子とネット上で利用可能な多くの例のおかげで、CまたはJavaでの実装がかなり簡単です。

問題は...私のチェックサム計算はVBScriptで実装する必要があります。

この言語での私の経験はほとんどありませんが、私の理解から、VBScriptでビットシフトを行うために提供されるものは何もありません。したがって、私は2による乗算と除算に依存しています。負の値を除いてうまく機能します。

私はいくつかのテストを実行しましたが、VBScriptは2の補数で16ビット整数を処理すると思います。

Q1:誰かが私にこれを確認できますか(VBScriptの2の補数)?MSDNWebサイトから正確な情報が見つかりませんでした。

Q2:負の数が2の補数でコード化されている場合、単純な数学演算でビットシフト(右と左)を行うことは可能ですか?

どうもありがとうございました。整数を「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の補数演算では、負の値が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です。(2の補数を使用して最も負の表現可能な数になるため、このように名付けられました。)興味深いことに、MINVAL2の補数の算術、x - y= x + NOT(y) + 1、およびMINVAL == 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 に答える