그래서 저는 작업중인 프로젝트 오일러 문제에 대한 링크드리스트를 사용하여 전체 무제한의 부호없는 정수 클래스를 구현했습니다. 모든 논리 비트 연산이 올바른지 확인했습니다 (그러나 볼 수 있으면 게시 할 수 있음). 이미 모든 운영자와 운영을 구현했습니다. 그러나 빼기 (및 그것을 사용하는 모든 것, 즉 나누기 및 모듈러스)는 작동하지 않습니다.무제한의 부호없는 정수 링크드 목록 구현입니다. 뺄셈이 작동하지 않습니다
LimitlessUnsigned limitless = 0x88888888u;
limitless = limitless << 4;
LimitlessUnsigned tester = 0x88888884u;
tester = tester << 4;
//limitless = limitless >> 5;
LimitlessUnsigned another = limitless - tester;
내가 디버거에서 다음과 같은 값을 얻을 : 나는 다음 테스트를 실행하면, 이것은 내가 무엇을 얻을
another LimitlessUnsigned
integerList std::__1::list<unsigned int, std::__1::allocator<unsigned int> >
[0] unsigned int 0b11111111111111111111111111111111
[1] unsigned int 0b00000000000000000000000001000000
limitless LimitlessUnsigned
integerList std::__1::list<unsigned int, std::__1::allocator<unsigned int> >
[0] unsigned int 0b00000000000000000000000000001000
[1] unsigned int 0b10001000100010001000100010000000
tester LimitlessUnsigned
integerList std::__1::list<unsigned int, std::__1::allocator<unsigned int> >
[0] unsigned int 0b00000000000000000000000000001000
[1] unsigned int 0b10001000100010001000100001000000
내가 뺄셈의 정의와 2의 뭔가를 놓친 것 같다 경의. 이 코드는 32 비트를 추가 할 때까지 작동합니다. 나는 처음 32에서 다음 32로 오버플로를 고려하고있다. 그러나 나는 (내가해야한다고 생각했듯이) 가장 높은 비트에서 오버플로를 버리고있다. 분명히, 나는 이것을 정확하게하지 않을 것이다. 아래는 관련 소스 코드입니다.
void LimitlessUnsigned::Sub(const LimitlessUnsigned& other)
{
if(*this <= other)
{
*this = 0u;
return;
}
LimitlessUnsigned temp = other;
while(temp.integerList.size() > integerList.size())
integerList.push_front(0u);
while(integerList.size() > temp.integerList.size())
temp.integerList.push_front(0u);
temp.TwosComp();
Add(temp, true);
}
void LimitlessUnsigned::Add(const LimitlessUnsigned& other, bool allowRegisterLoss)
{
LimitlessUnsigned carry = *this & other;
LimitlessUnsigned result = *this^other;
while(carry != 0u)
{
carry.ShiftLeft(1, allowRegisterLoss);
LimitlessUnsigned shiftedcarry = carry;
carry = result & shiftedcarry;
result = result^shiftedcarry;
}
*this = result;
}
void LimitlessUnsigned::Not()
{
for(std::list<unsigned>::iterator iter = integerList.begin(); iter != integerList.end(); ++iter)
{
*iter = ~*iter;
}
}
void LimitlessUnsigned::TwosComp()
{
Not();
Add(1u, true);
}
void LimitlessUnsigned::ShiftLeft(unsigned shifts, bool allowRegisterLoss)
{
unsigned carry = 0u;
bool front_carry = false;
while(shifts > 0u)
{
if((integerList.front() & CARRY_INT_HIGH) == CARRY_INT_HIGH)
front_carry = true;
for(std::list<unsigned>::reverse_iterator iter = integerList.rbegin(); iter != integerList.rend(); ++iter)
{
unsigned temp = *iter;
*iter = *iter << 1;
*iter = *iter | carry;
if((temp & CARRY_INT_HIGH) == CARRY_INT_HIGH)
carry = CARRY_INT;
else
carry = 0u;
}
carry = 0u;
if(front_carry && !allowRegisterLoss)
{
front_carry = false;
integerList.push_front(1u);
}
--shifts;
}
}
업데이트 나는 마지막으로 문제를 해결했다. 여기 내 블로그 게시물은 소스 코드와 함께입니다 :
http://memmove.blogspot.com/2013/04/unlimited-unsigned-integer-in-c.html
모든 것을 부호없는 것으로 처리하기 때문에 2의 보수를 만들 때 거대한 양수로 처리 한 다음 빼기 대신 이것을 더합니다. – Barmar
@Barmar 글쎄, 나는 프론트()를 칠 때까지 하위 멤버들로부터 상위 멤버들로 비트를 이동시키고있다. 그런 다음 나는 그것이 떨어지게했습니다. 거대한 양수로 취급하지 않습니까? 추적을 보면 맨 아래쪽 목록 구성원이 차이점에 맞습니다. –
2의 보수를 추가하여 부호없는 빼기를 수행하는 것은 모듈러 산술에서만 작동합니다. 무한 정밀도 산술 연산을 사용하면 계속 추가하고 랩하지 않습니다. – Barmar