업데이트을 아래에 내 원래의 분석이 잘못되었습니다 ...
불행히도, 나는의 동작에 대해 올바르지 않습니다. C#은 왼쪽 시프트 연산자가 오른쪽 피연산자의 하위 5 비트로 시프트 수를 제한 할 것을 강요합니다 (64 비트 왼쪽 시프트를위한 6 비트 피연산자). 따라서 원래 코드는 C#에서 잘 정의되어 있고 정확합니다 (C/C++에서 정의되지 않은 동작 임). 기본적으로,이 시프트 식 :
(this.Array[i] << shift)
은 동일합니다 : 나는 아마 아직도 만들기 위해 변화를 변경할 것
(this.Array[i] << (shift & 0x1f))
(즉 명시 경우 다른 이유로 내가 그 코드 6 보았다 때 몇 달 후에 나는 동일한 실수 분석을 통해 우연히 발견하지 않을 것입니다.) if (shift == 32)
수표 대신 위의 방법을 사용하십시오.
원래 분석 :
확인, 그래서 여기에 두 번째 대답. 가장 중요한 점은 원래 솔루션에 ImmutableBitArray
의 비트 길이가 32 비트의 배수 인 경우에 버그가 있다는 것인데, 배열 요소와 다른 두 개의 배열에 대해 true
을 반환 할 것입니다.
예를 들어, 비트 길이가 다른 ImmutableBitArray
을 고려하십시오. 원래 Equals()
방법은 하나의 시프트 연산을 수행하고 배열 만 Int32
것 -하지만, 다음을 의미한다 (32)
로 평가한다
int shift = 0x20 - (this.length % 0x20);
때문에, 값 32 비트 시프트 것 테스트 :
if (this.Array[i] << shift != other.Array[i] << shift)
는 (0 != 0)
테스트 것 때문에 return false
이 실행되지 않습니다.
나는 여러분의 Equals()
메소드를 다음과 같이 중대한 변화가 아닌 것으로 바꿀 것입니다 - 저는 위에서 언급 한 버그를 처리하고 엄격하게 스타일과 관련된 몇 가지 다른 것들을 변경한다고 생각합니다. 너에게 어떤 관심도 가져라. 또한 실제로 컴파일되지 않은 점에 유의 내 Equals()
방법을 테스트, 그래서 거기에 버그 (또는 적어도 구문 오류)하는 거의 100 %의 확률로있다 : 엄밀히 말하면
public bool Equals(ImmutableBitArray other)
{
if (this.length != other.length)
{
return false;
}
int finalIndex = this.Array.Length - 1;
for (int i = 0; i < finalIndex; i++)
{
if (this.Array[i] != other.Array[i])
{
return false;
}
}
// check the last array element, making sure to ignore padding bits
int shift = 32 - (this.length % 32);
if (shift == 32) {
// the last array element has no padding bits - don't shift
shift = 0;
}
if (this.Array[finalIndex] << shift != other.Array[finalIndex] << shift)
{
return false;
}
return true;
}
주, 원래 GetHashCode()
은 메서드는 비록 비트 길이가 32의 배수 일 때 마지막 요소에서 제대로 섞이지 않더라도 같은 객체가 여전히 동일한 해시 코드를 반환하기 때문에 동일한 결함이 있음에도 불구하고 도청되지 않습니다. 하지만 난 여전히 같은 방법으로 결함을 해결하기로 결정했습니다 GetHashCode()
.
배열 구성원의 유형은 무엇입니까? –
배열은 Int32입니다. [] –