// // Created by trotfunky on 04/11/2020. // #include #include "NegBin.h" NegBin::NegBin(longBitField binaryRepresentation) : value(binaryRepresentation.to_ulong()) {} NegBin::NegBin(long decimalValue) : value(0) { unsigned int currentPower = 0; decimalValue *= -1; // This works by checking the remainder by -2, giving the lowest bit of the converted number. // Then, shift to the right to drop the bit we just checked and start again until every set bit has been checked. // The sign flips each time as we are in base -2 and not 2. // Miiight be UDB... while (decimalValue != 0) { value |= std::abs(decimalValue%-2) << currentPower; decimalValue = -decimalValue >> 1; currentPower++; } } NegBin& NegBin::operator+=(const NegBin& rhs) { unsigned long carry = 0; for(unsigned int i = 0;i> i; unsigned long temp_rhs = rhs.value >> i; unsigned long temp_lhs = this->value >> i; // Nothing remaining to add if (!(temp_rhs | temp_carry)) break; // Both carry and right hand side are 1 so we need to add a carry if (temp_carry & temp_rhs & 1) { // If the carry is already set for this bit, it needs to be cleared for this bit and the next if (temp_carry >> 1 & 1) { carry &= ~(0b11 << i); } else { // Else add a two bit carry carry |= 0b11 << (i+1); } } // If either of them are set, add to lhs, otherwise don't bother else if ((temp_carry ^ temp_rhs) & 1) { // If a carry was already set for the next bit too, discard both carries and the current bit if (temp_lhs & temp_carry & 1 && temp_carry >> 1 & 1) { carry &= ~(0b11 << i); this->value &= ~(0b1 << i); } else if (temp_lhs & 1) { // If the current bit was set, clear and add a two bit carry carry |= 0b11 << (i+1); this->value &= ~(0b1 << i); } else { this->value |= 0b1 << i; } } } return *this; } NegBin operator+(NegBin lhs, const NegBin& rhs) { lhs += rhs; return lhs; } NegBin& NegBin::operator-=(const NegBin& rhs) { // lhs - rhs <=> lhs + (-rhs) *this += ~rhs; return *this; } NegBin operator-(NegBin lhs, const NegBin& rhs) { lhs -= rhs; return lhs; } NegBin& NegBin::operator*=(const int& rhs) { auto unit = *this; for (int i=0;i> 1; } NegBin NegBin::operator>>(const int& rhs) { this->value >>= rhs; return *this; } NegBin NegBin::operator<<(const int& rhs) { this->value <<= rhs; return *this; } NegBin::operator long() const { long result = 0; for(unsigned int i = 0;i> i) & 1)*std::pow(-2,i); } return result; } NegBin operator ""_nb(unsigned long long number) { return NegBin(longBitField(number)); } std::ostream& operator<<(std::ostream& ostream, const NegBin& number) { ostream << static_cast(number); return ostream; }