2012-04-30 20 views
6

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

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

この言語での私の経験はほとんどありませんが、私の理解では、VBScriptでビットシフトを行うためのものは何もありません。したがって、私はの乗算と2つの除算に頼っています。の負の値を除いては正常に動作します。

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

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

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

ありがとう、私は本当に '1'と '0'の配列またはVBScriptからいくつかのJava/Cアプリケーションを呼び出す整数として扱うようなkludgeを避けたいと思います。

EDITは、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)。

+0

はあなたのコードを配っためにどうもありがとうございます! 32ビットを除いて全く同じものが必要でしたが、これはあなたのコードでは簡単でした。私はCRC32を実装しています。 :) –

答えて

5

2の補数演算では、2で右にシフトすると負の値が発生する唯一の影響があります。意図した右シフトが行われますが、最上位ビットに新しい1ビットが導入されます - MSB)「負の値を保持」する立場元の値がでない限り、すべてのビットが0だからこれを補正するためになった場合には-1を、次の擬似コードを試してみてください。

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を追加すると、2の補数演算であるx - y = x + NOT(y) + 1MINVAL == NOT(MINVAL) + 1のため、上記の疑似コードでそれを減算するだけでなく、同様に機能します。

負の数の乗算を使用した左シフトは、正の数の場合と同じように、負の数の場合も同様です。

+0

それは完璧です!この説明をありがとう!それは今の魅力のように機能します。 – Jerome

+0

あなたは大歓迎です:) –

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#にはシフト演算子が組み込まれています。これは教育目的に過ぎません。

-1

これは非常に遅いです、これを試してください。以下の値> = 0のための作品が、 bitshifts> 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ビット整数で使用できます。配列はbitshifts> 30との境界配列の添え字のうち、Thowさんになる32ビット整数の場合

は次のとおりです。

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)