are these correct implementations of the operator<< and >> for bitshifting? for some reason, in my operator/, where it only involves these 2 operators, something is allowing for a silly jump that is causing division to be done incorrectly.
// the value is stored msb in a list of uint8_t
// so 0x123456 will be stored in the list as {0x12, 0x34, 0x56}
integer operator<<(size_t shift){
std::list <uint8_t> out = value;
for(unsigned int i = 0; i < (shift >> 3); i++)
out.push_back(0);
shift &= 7;
if (shift){
out.push_front(0);
std::list <uint8_t>::iterator i = out.begin(), j = out.end();
i++; j--;
for(; i != j; i++){
uint8_t temp = *i >> (8 - shift);
--i;
*i += temp;
i++;
*i = (uint8_t) (*i << shift);
}
uint8_t temp = *i >> (8 - shift);
i--;
*i += temp;
i++;
*i <<= shift;
}
return integer(out);
}
integer operator>>(size_t shift){
std::list <uint8_t> out = value;
for(unsigned int i = 0; i < (shift >> 3); i++)
out.pop_back();
shift &= 7;
if (shift){
std::list <uint8_t>::reverse_iterator i = out.rbegin(), j = out.rend();
j--;
for(; i != j; i++){
*i >>= shift;
i++;
uint8_t temp = *i << (8 - shift);
i--;
*i += temp;
}
*j >>= shift;
}
return integer(out);
}
heres what im doing:
integer(1234567) / integer(6)
inside division algorithm (long division):
numerator largest multiple of denomiator < numeator
12d687 0c0000
06d687 060000
d687 c000
1687 0c00
0a87 0600
0487 0300
0187 0c <-- where did this come from??
017b 0180
is the error in one of the operators shown or in some other operator?
heres my entire code: http://ideone.com/ncq9S
Does this really need to be parameterized? It would seem that any shift quantity can be stored in a
size_t, and converting tosize_timplicitly or explicitly would be a good idea before starting the rest of the process.Usually binary
operatorfunctions are best implemented as non-memberfriends. For example, fewer conversions are considered when producing thethispointer than for generic operands. I’d writefriend integer operator<< ( integer lhs, size_t shift ).If you use a
friendand pass-by-value, then this copy is made implicitly. The compiler also has an easier time eliminating it if you are really just modifying one object, e.g.q = q << 3.Be careful in the loop condition. You’re applying an operator to a high-level type, which might cause an expensive computation (or even endless recursion if
Tisinteger!At this point, if
shift == 0you are done. Best to insert a conditionalreturnhere. Also, now the range is really limited, so assign to a narrower type thanT.This is only necessary if the byte will be nonzero. Probably best to special-case the first operation and make the
push_frontconditional, instead of special-casing the last.… Hmm, it looks like the
operator>>is being exercised more… skipping to that…Clearly the
>>operator is missing from the loop. Try*i = *i >> shift + temp. Also, I don’t see how the list ever gets shorter. Is that done ininteger::integer( list<…> )?However, I can’t really see what produces the behavior in the posted output. The leading zero is probably a result of the unconditional
push_frontinoperator<<, but the pattern I’d expect isc,6,3,18,c, …. You don’t seem to be repeating any sequence, but instead jump randomly.Maybe the division code, or the class constructor could provide clues.