#include "Fixed.hpp" /* * functions to print numbers in binary * for the float, found help from stackoverflow : * https://stackoverflow.com/questions/474007/floating-point-to-binary-valuec */ std::string printBitsInt(int num) { int i = 0; for (unsigned int mask = 1U << (sizeof(int) *8 -1); mask; mask >>= 1) { std::cout << ((num & mask) != 0); i++; if (i == 1 || i == 9 || i == 24) std::cout << ' '; } return ""; } std::string printBitsFloat(float num) { int *p = (int *)# int i = 0; for (unsigned int mask = 1U << (sizeof(float) *8 -1); mask; mask >>= 1) { std::cout << ((*p & mask) != 0); i++; if (i == 1 || i == 9 || i == 24) std::cout << ' '; } return ""; } /* * statics variables initialisation * * for MAX integer : * 00000000 01111111 11111111 11111111 ( 8388607) (-1U >> (this->_frac +1)) * <= ... >= * 11111111 10000000 00000000 00000000 (-8388608) * */ int const Fixed::_frac = 8; int const Fixed::_max = -1U >> (_frac +1); /* * default constructor / copy constructor / destructor */ Fixed::Fixed() : _value(0) { return; } Fixed::Fixed(Fixed const & src) { *this = src; return; } Fixed::~Fixed( void ) { return; } /* * int and float constructors */ Fixed::Fixed(int integer) { if (integer < ~this->_max || integer > this->_max) std::cout << "error: integer out of range" << '\n'; else this->_value = integer << this->_frac; } Fixed::Fixed(float const floater) { if (floater < ~this->_max || floater > this->_max) std::cout << "error: float out of range" << '\n'; else this->_value = roundf(floater * (1 << this->_frac)); } /* * assignement operator */ Fixed & Fixed::operator=( Fixed const & rhs ) { if ( this != &rhs ) this->_value = rhs.getRawBits(); return *this; } /* * operators < ; > ; <= ; == ; != ; + ; - ; * ; / ; ++ ; -- * ref : https://en.cppreference.com/w/cpp/language/operators * for division, if you want to avoid floats (legitimate) : * https://stackoverflow.com/questions/8506317/fixed-point-unsigned-division-in-c */ bool Fixed::operator< (Fixed const & rhs) const { return this->toFloat() < rhs.toFloat(); } bool Fixed::operator> (Fixed const & rhs) const { return this->toFloat() > rhs.toFloat(); } bool Fixed::operator<=(Fixed const & rhs) const { return this->toFloat() <= rhs.toFloat(); } bool Fixed::operator>=(Fixed const & rhs) const { return this->toFloat() >= rhs.toFloat(); } bool Fixed::operator==(Fixed const & rhs) const { return this->toFloat() == rhs.toFloat(); } bool Fixed::operator!=(Fixed const & rhs) const { return this->toFloat() != rhs.toFloat(); } Fixed Fixed::operator+ ( Fixed const & rhs ) const { Fixed result(*this); result._value += rhs._value; return (result); } Fixed Fixed::operator- ( Fixed const & rhs ) const { Fixed result(*this); result._value -= rhs._value; return (result); } Fixed Fixed::operator* ( Fixed const & rhs ) const { Fixed result(*this); int left = this->_value; int right = rhs._value; result._value = 0; // left:5 right:10 while (right > 0) // 1 { result._value /= 10; // 0/10 = 0 0/10 = 0 result._value += (left * (right % 10)); // 0+(5*0) = 0 0+(5*1) = 1 std::cout << "intermediaire: " << result << " "; // right /= 10; // 10/10 = 1 1/10 = 0 } result._value >>= _frac; // result._value *= rhs._value >> _frac; // result._value += (this->_value * (rhs._value & ((1 << (_frac + 1)) - 1))) >> _frac; // result._value = ((long)result._value * (long)rhs._value) >> 8; return result; // // 47 * 256 = 12 032 // 5 * 10 -> 5*256 * 10*256 -> 5 * 10 * 256^2 // 256^2 = 65 536 // 256 : 1 00000000 // 65 536 : 1 00000000 00000000 // // // 5 * 10 = 50 // 101 * 1010 = 110010 // 101.00000000 * 1010.00000000 = 110010.00000000 // 101 00000000 * 1010 00000000 = 110010 00000000 // 110010 00000000 // 128 * 2560 = 327680 // // // 3 * 5 = 15 // 11 * 101 = 1111 // // // 3.5 * 5.25 = 18.375 // 11.1 * 101.01 = 10010.011 // 11 1 * 101 01 = 10010 011 // 7 * 21 = 147 // // // 3.5 * 5.25 // 3.5 * (5 + 0.25) // 3.5 * 5 // + 3.5 * 0.25 // // 3.5 * 4.25 = 14.875 // 3.5 * (0.05 + 0.20 + 4.00) // 3.5 * 0.05 = 0.175 = 17.5 / 100 // 3.5 * 0.20 = 0.7 = 7 / 10 // 3.5 * 4.00 = 14 // 14 + 0.7 + 0.175 = 14.875 // // 3.5 * 5 = 17.5 // 3.5 * 2 = 7 // 3.5 * 4 = 14 // (((17.5 / 10) + 7) / 10) + 14 // 17.5 / 10 // 1.75 + 7 // 8.75 / 10 // 0.875 + 14 // } Fixed Fixed::operator/ ( Fixed const & rhs ) const { std::cout << this->_value << " " << rhs._value << " " << (( (this->_value << 8) / rhs._value )) << "\n"; return Fixed( this->toFloat() / rhs.toFloat() ); } Fixed Fixed::operator++() { this->_value++; return *this; } Fixed Fixed::operator--() { this->_value--; return *this; } Fixed Fixed::operator++( int ) { Fixed old = *this; Fixed::operator++(); return old; } Fixed Fixed::operator--( int ) { Fixed old = *this; Fixed::operator--(); return old; } /* * returns min and max */ Fixed const & Fixed::min(Fixed const & lhs, Fixed const & rhs) { if (lhs < rhs) return lhs; return rhs; } Fixed const & Fixed::max(Fixed const & lhs, Fixed const & rhs) { if (lhs > rhs) return lhs; return rhs; } Fixed & Fixed::min(Fixed & lhs, Fixed & rhs) { if (lhs < rhs) return lhs; return rhs; } Fixed & Fixed::max(Fixed & lhs, Fixed & rhs) { if (lhs > rhs) return lhs; return rhs; } /* * functions that returns _value */ int Fixed::getRawBits( void ) const { return this->_value; } void Fixed::setRawBits( int const raw ) { this->_value = raw; } int Fixed::toInt( void ) const { return (this->_value >> this->_frac); } float Fixed::toFloat( void ) const { return ((float)this->_value / (float)(1 << this->_frac)); } /* * overload "<<" -> output fixed point in float representation * found here : https://github.com/pgomez-a/42_CPP_Piscine/blob/master/cpp02/ex01/Fixed.cpp */ std::ostream & operator<<(std::ostream & o, Fixed const & rhs) { o << rhs.toFloat(); return (o); }