2012-04-30 4 views
6

파일의 내용을 확인하기 위해 체크섬 (CRC16 CCITT)을 구현해야합니다. 체크섬은 < < 및 >> 연산자와 그물에서 사용할 수있는 많은 예제 덕분에 C 또는 Java로 구현하기가 다소 쉽습니다.아무 것도 없을 때 비트 시프트 ... 비트 시프트 연산자

문제는 ... 내 체크섬 계산은 VBScript에서 구현되어야합니다.

이 언어에 대한 나의 경험은 거의 없지만 내 이해에 따르면 VBScript에서 비트 시프트를 수행하기 위해 제공된 것은 없습니다. 그러므로 저는 의 곱셈과 나눗셈에 의존합니다.음수 값을 제외하고는 잘 작동합니다.

나는 몇 가지 테스트를 수행했으며 VBScript는 16 비트 정수를 2의 보수로 처리한다고 생각합니다.

1 : 누군가이 사실을 (VBScript의 2의 보수) 확인할 수 있습니까? MSDN 웹 사이트에서 정확한 정보를 찾지 못했습니다.

Q2 : 음수가 2의 보수로 코딩되면 간단한 수학 연산으로 비트 시프트 (오른쪽 및 왼쪽)를 수행 할 수 있습니까?

.

고마워, 나는 '1'과 '0'의 배열이나 VBScript에서 java/c 앱을 호출하는 정수처럼 다루기를 정말로 피하고 싶다. 값이 때때로 때문에 16 비트를 초과 한 나는 마스크했다 : 위의 코드에 대한

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 

참고 :

편집이 도움을 주셔서 감사합니다, VBScript를에서 오른쪽 시프트의 내 구현을 검색 할 수 있습니다 오버플로를 피하기 위해 사용되지 않는 비트 (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입니다. (2의 보수를 사용하여 가장 음수로 표현할 수있는 숫자이기 때문에 이름이 붙여졌습니다.) 흥미롭게도 덧셈 연산은 x - y = x + NOT(y) + 1MINVAL == NOT(MINVAL) + 1이므로 위의 의사 코드에서 덧셈 연산을 덧붙여 사용하는 것뿐 아니라 MINVAL을 더하는 것이 좋습니다.

음수에 대해 곱하기 2를 사용하는 왼쪽 시프트는 양수에 대해서도 마찬가지입니다.

+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)