Fixed.cpp
1 #include "Fixed.hpp" 2 #include <cmath> 3 4 Fixed::Fixed() : _value(0) { 5 // Default constructor 6 std::cout << "Default constructor called" << std::endl; 7 } 8 9 Fixed::Fixed(const Fixed &other) : _value(other._value) { 10 std::cout << "Copy constructor called" << std::endl; 11 } 12 13 Fixed::Fixed(const int &other) : _value(other << _fractionalBits) { 14 std::cout << "Int constructor called" << std::endl; 15 } 16 17 Fixed::Fixed(const float &other) { 18 // Use roundf to convert the float into the fixed-point representation 19 // by multiplying by 2^_fractionalBits and rounding to nearest. 20 _value = static_cast<int>( 21 roundf(other * static_cast<float>(1 << _fractionalBits))); 22 23 std::cout << "Float constructor called" << std::endl; 24 } 25 26 Fixed &Fixed::operator=(const Fixed &other) { 27 if (this != &other) { 28 _value = other._value; 29 } 30 std::cout << "Copy assignment operator called" << std::endl; 31 return *this; 32 } 33 34 Fixed::~Fixed() { std::cout << "Destructor called" << std::endl; } 35 36 std::ostream &operator<<(std::ostream &os, const Fixed &obj) { 37 os << obj.toFloat(); 38 return os; 39 } 40 41 bool Fixed::operator>(const Fixed &other) const { 42 return _value > other._value; 43 } 44 45 bool Fixed::operator<(const Fixed &other) const { 46 return _value < other._value; 47 } 48 49 bool Fixed::operator>=(const Fixed &other) const { 50 return _value >= other._value; 51 } 52 53 bool Fixed::operator<=(const Fixed &other) const { 54 return _value <= other._value; 55 } 56 57 bool Fixed::operator==(const Fixed &other) const { 58 return _value == other._value; 59 } 60 61 bool Fixed::operator!=(const Fixed &other) const { 62 return _value != other._value; 63 } 64 65 Fixed Fixed::operator+(const Fixed &other) const { 66 // We find wich of the two values has more fractional bits 67 // and we align the other value to that before adding 68 Fixed result; 69 70 int selfFracBits = getFractionalBits(); 71 int otherFracBits = other.getFractionalBits(); 72 73 if (selfFracBits >= otherFracBits) { 74 result._value = _value + (other._value << (selfFracBits - otherFracBits)); 75 } else { 76 result._value = (_value << (otherFracBits - selfFracBits)) + other._value; 77 } 78 79 return result; 80 } 81 82 Fixed Fixed::operator-(const Fixed &other) const { 83 // We find wich of the two values has more fractional bits 84 // and we align the other value to that before subtracting 85 Fixed result; 86 87 int selfFracBits = getFractionalBits(); 88 int otherFracBits = other.getFractionalBits(); 89 90 if (selfFracBits >= otherFracBits) { 91 result._value = _value - (other._value << (selfFracBits - otherFracBits)); 92 } else { 93 result._value = (_value << (otherFracBits - selfFracBits)) - other._value; 94 } 95 96 return result; 97 } 98 99 Fixed Fixed::operator*(const Fixed &other) const { 100 // Multiply two fixed-point values. 101 // Use 64-bit intermediate to avoid overflow during multiplication, 102 // then shift back by fractional bits. Add rounding for nearest. 103 Fixed result; 104 105 int fb = getFractionalBits(); 106 int64_t prod = 107 static_cast<int64_t>(_value) * static_cast<int64_t>(other._value); 108 109 // Rounding: add 0.5 in fixed-point (1 << (fb-1)) for positive values, 110 // subtract for negative to round toward nearest. 111 int64_t rounding = 112 (prod >= 0) ? (int64_t(1) << (fb - 1)) : -(int64_t(1) << (fb - 1)); 113 114 prod = (prod + rounding) >> fb; 115 116 result._value = static_cast<int>(prod); 117 return result; 118 } 119 120 Fixed Fixed::operator/(const Fixed &other) const { 121 // Divide two fixed-point values. 122 // Use 64-bit intermediate to avoid overflow during shifting, 123 // then shift back by fractional bits. Add rounding for nearest. 124 Fixed result; 125 126 int fb = getFractionalBits(); 127 if (other._value == 0) { 128 std::cerr << "Error: Division by zero in Fixed::operator/" << std::endl; 129 result._value = 0; 130 return result; 131 } 132 133 int64_t dividend = (static_cast<int64_t>(_value) << fb); 134 int64_t divisor = static_cast<int64_t>(other._value); 135 136 // Rounding: add half the divisor for positive values, 137 // subtract for negative to round toward nearest. 138 int64_t rounding = (dividend >= 0) ? (divisor / 2) : -(divisor / 2); 139 140 dividend += rounding; 141 142 int64_t quot = dividend / divisor; 143 144 result._value = static_cast<int>(quot); 145 return result; 146 } 147 148 Fixed &Fixed::operator++() { 149 int new_value = _value + (1 << _fractionalBits); 150 _value = new_value; 151 return *this; 152 } 153 154 Fixed Fixed::operator++(int) { 155 // Postfix increment 156 Fixed temp = *this; 157 _value += (1 << _fractionalBits); 158 return temp; 159 } 160 161 Fixed &Fixed::operator--() { 162 // Prefix decrement: subtract one unit in fixed-point (1 << fractional bits) 163 _value -= (1 << _fractionalBits); 164 return *this; 165 } 166 167 Fixed Fixed::operator--(int) { 168 // Postfix decrement 169 Fixed temp = *this; 170 _value -= (1 << _fractionalBits); 171 return temp; 172 } 173 174 float Fixed::toFloat() const { 175 return static_cast<float>(_value) / (1 << _fractionalBits); 176 } 177 178 Fixed &Fixed::min(Fixed &a, Fixed &b) { return (a < b) ? a : b; } 179 180 const Fixed &Fixed::min(const Fixed &a, const Fixed &b) { 181 return (a < b) ? a : b; 182 } 183 184 Fixed &Fixed::max(Fixed &a, Fixed &b) { return (a > b) ? a : b; } 185 186 const Fixed &Fixed::max(const Fixed &a, const Fixed &b) { 187 return (a > b) ? a : b; 188 } 189 190 int Fixed::getRawBits() const { return _value; } 191 192 int Fixed::getFractionalBits() { return _fractionalBits; }