2012-03-17 3 views
2

몇 가지 포럼에서 이미이 질문을했지만 위의 코드를 C#에서 Visual Basic으로 변환 할 수없는 이유에 대해서는 설명하지 않았습니다.VB.NET에서 GetStableHash 메서드를 구현하는 방법

코드는 실제로이 포럼의 C#으로 작성되었습니다. (the source)

static public int GetStableHash(string s) 
     { 
      uint hash = 0; 
      // if you care this can be done much faster with unsafe 
      // using fixed char* reinterpreted as a byte* 
      foreach (byte b in System.Text.Encoding.Unicode.GetBytes(s)) 
      { 

       hash += b; 
       hash += (hash << 10); 
       hash ^= (hash >> 6); 

      } 
      // final avalanche 
      hash += (hash << 3); 
      hash ^= (hash >> 11); 
      hash += (hash << 15); 
      // helpfully we only want positive integer < MUST_BE_LESS_THAN 
      // so simple truncate cast is ok if not perfect 
      return (int)(hash % MUST_BE_LESS_THAN); 
     } 

그래서, 코드가한다고는 VB.NET

Const MUST_BE_LESS_THAN As Integer = 100000000 

Function GetStableHash(ByVal s As String) As Integer 


    Dim hash As UInteger = 0 

    For Each b as Byte In System.Text.Encoding.Unicode.GetBytes(s) 
     hash += b 
     hash += (hash << 10) 
     hash = hash Xor (hash >> 6) 
    Next 

    hash += (hash << 3) 
    hash = hash Xor (hash >> 11) 
    hash += (hash << 15) 

    Return Int(hash Mod MUST_BE_LESS_THAN) 
End Function 

바로 것 같다에서 그런 일이 될,하지만 그것은 작동하지 않습니다. VB.NET에서는 "hash + = (해쉬 < < 10)"이

답변

4

인데 오버플로 검사는 기본적으로 C#에서는 해제되어 있지만 VB.NET에서는 기본적으로 해제되어 있습니다. 프로젝트 + 속성, 컴파일 탭, 아래로 스크롤, 고급 컴파일 옵션 및 "정수 오버플로 검사 제거"옵션을 선택하십시오.

불편한 경우 코드를 별도의 클래스 라이브러리 프로젝트로 옮기십시오. 따라서 설정을 변경해도 나머지 코드에는 영향을 미치지 않습니다. 그 다른 프로젝트는 이제 C# 프로젝트가 될 수도 있습니다.

+0

VB.net에서 파일/파일의 일부분에 대한 오버플로 검사를 변경할 방법이 없습니까? C#'unchecked' 키워드와 비슷합니까? – CodesInChaos

+0

아니요, 해당 언어로 된 키워드가 없습니다. 언어 구문에 의해 오버플로 검사가 가정됩니다. 그래서 바이트에 int를 할당하기 위해 캐스트하지 않아도됩니다. –

0

한스가 설명했듯이 VB는 오버플로 검사를하고 C#은 에러가 발생했습니다. 오버플로 검사가 없으면 추가 비트가 단순히 버려집니다. 계산 중에 더 큰 데이터 유형을 사용하고 수동으로 여분의 비트를 버리면이 동일한 동작을 복제 할 수 있습니다. 그것은 코드의 엑스트라 라인, 또는 코드의 3 여분의 줄 당신이 답변을 정확히 C 번호와 일치 할 경우 (주석을 찾아)을 취

는 약간 다른 결과를 확인하는 경우
Public Shared Function GetStableHash(ByVal s As String) As Integer 

    ' Use a 64-bit integer instead of 32-bit 
    Dim hash As ULong = 0 

    For Each b As Byte In System.Text.Encoding.Unicode.GetBytes(s) 
    hash += b 
    hash += (hash << 10) 
    ' Throw away all bits beyond what a UInteger can store 
    hash = hash And UInteger.MaxValue 
    hash = hash Xor (hash >> 6) 
    Next 

    hash += (hash << 3) 
    ' Throw away all extra bits 
    hash = hash And UInteger.MaxValue 
    hash = hash Xor (hash >> 11) 
    hash += (hash << 15) 
    ' Throw away all extra bits 
    hash = hash And UInteger.MaxValue 

    Return Int(hash Mod MUST_BE_LESS_THAN) 
End Function 

(그러나 동등하게 유효) C# 코드가 생성하는 코드에서 필요한 유일한 코드 행은 For Each 루프 내부 코드입니다. 다른 두 개는 삭제할 수 있습니다.

관련 문제