c++ - Unlimited Unsigned Integer linked-list implementation. Subtraction not working -


so, have implemented entire unlimited unsigned integer class using linked-list project euler problem working on. have verified of logical bit operations correct (though can post if want see them). have implemented operators , operations. however, subtraction (and using it, i.e. division , modulus) doesn't work. when run following test, get:

  limitlessunsigned limitless = 0x88888888u;   limitless = limitless << 4;    limitlessunsigned tester = 0x88888884u;   tester = tester << 4;    //limitless = limitless >> 5;   limitlessunsigned = limitless - tester; 

i following values debugger:

    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 

it seems have missed definition of subtraction , two's compliment. code works until need add 32 bits. accounting overflow, first 32 next 32. however, discarding overflow on highest bit (as thought should). obviously, not doing correctly. below relevant source code.

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;       } } 

update solved problem. here blog post along source code:

http://memmove.blogspot.com/2013/04/unlimited-unsigned-integer-in-c.html

after taking two's complement adding, uses 0 extension when widths not equal. when extend subtrahend (now addend) wide minuend, need use sign extension, not 0 extension. because two's complement value needs treated in context negative number (despite being unsigned elsewhere). alternatively (and perhaps more in keeping overall design), subtrahend , minuend must same width before starting two's complement business.

you're doing this:

0110 - 10 = 0110 + (~(10) + 1)           = 0110 + (01 + 1)           = 0110 + 10           = 0110 + 0010           = 1000 

when should be:

0110 - 10 = 0110 + (~(10) + 1)           = 0110 + (01 + 1)           = 0110 + 10           = 0110 + 1110  <= sign-extended subtrahend           = 0100 

or alternatively:

0110 - 10 = 0110 - 0010  <= widths equalized           = 0110 + (~(0010) + 1)           = 0110 + (1101 + 1)           = 0110 + 1110           = 0100 

Comments

Popular posts from this blog

Why does Ruby on Rails generate add a blank line to the end of a file? -

keyboard - Smiles and long press feature in Android -

node.js - Bad Request - node js ajax post -