From 726bd388dd202b0666e7341db0bac401dc8995a6 Mon Sep 17 00:00:00 2001 From: Hugo LAMY Date: Fri, 18 Mar 2022 14:26:15 +0100 Subject: [PATCH] d07 ajouts tests avec fixed et char dans ex01 et ex02 --- d07/ex00/Makefile | 10 +- d07/ex00/headers/Fixed.hpp | 55 +++++++ d07/ex00/{ => headers}/Templates.hpp | 0 d07/ex00/{ => headers}/colors.h | 0 d07/ex00/main.cpp | 77 +++++++-- d07/ex00/srcs/Fixed.cpp | 225 +++++++++++++++++++++++++++ d07/ex01/Fixed.cpp | 225 +++++++++++++++++++++++++++ d07/ex01/Makefile | 7 +- d07/ex01/headers/ClassTest.hpp | 20 +++ d07/ex01/headers/Fixed.hpp | 55 +++++++ d07/ex01/iter | Bin 0 -> 25144 bytes d07/ex01/main.cpp | 20 ++- d07/ex02/Fixed.cpp | 225 +++++++++++++++++++++++++++ d07/ex02/Makefile | 6 +- d07/ex02/array | Bin 0 -> 77664 bytes d07/ex02/headers/Array.hpp | 21 ++- d07/ex02/headers/Fixed.hpp | 55 +++++++ d07/ex02/main.cpp | 128 ++++++++++++++- 18 files changed, 1098 insertions(+), 31 deletions(-) create mode 100644 d07/ex00/headers/Fixed.hpp rename d07/ex00/{ => headers}/Templates.hpp (100%) rename d07/ex00/{ => headers}/colors.h (100%) create mode 100644 d07/ex00/srcs/Fixed.cpp create mode 100644 d07/ex01/Fixed.cpp create mode 100644 d07/ex01/headers/ClassTest.hpp create mode 100644 d07/ex01/headers/Fixed.hpp create mode 100755 d07/ex01/iter create mode 100644 d07/ex02/Fixed.cpp create mode 100755 d07/ex02/array create mode 100644 d07/ex02/headers/Fixed.hpp diff --git a/d07/ex00/Makefile b/d07/ex00/Makefile index e474bc5..58ef36a 100644 --- a/d07/ex00/Makefile +++ b/d07/ex00/Makefile @@ -28,12 +28,14 @@ LIBS = INCLUDES = -I$(D_HEADERS) -D_SRCS = . -SRCS = main.cpp +D_SRCS = srcs +SRCS = main.cpp \ + Fixed.cpp -D_HEADERS = . +D_HEADERS = headers HEADERS = colors.h \ - Templates.hpp + Templates.hpp \ + Fixed.hpp D_OBJS = builds OBJS = $(SRCS:%.$(EXT)=$(D_OBJS)/%.o) diff --git a/d07/ex00/headers/Fixed.hpp b/d07/ex00/headers/Fixed.hpp new file mode 100644 index 0000000..b63a80c --- /dev/null +++ b/d07/ex00/headers/Fixed.hpp @@ -0,0 +1,55 @@ +#ifndef FIXED_HPP +# define FIXED_HPP + +#include +#include +#include + +class Fixed { + +public: + + Fixed(void); // default/parametric constructor + Fixed(Fixed const & src); // copy constructor + ~Fixed(void); // destructor + Fixed(int integer); + Fixed(float const floater); + + Fixed & operator= (Fixed const & rhs); // assignement operator + bool operator< (Fixed const & rhs) const; + bool operator> (Fixed const & rhs) const; + bool operator<=(Fixed const & rhs) const; + bool operator>=(Fixed const & rhs) const; + bool operator==(Fixed const & rhs) const; + bool operator!=(Fixed const & rhs) const; + Fixed operator+ (Fixed const & rhs) const; + Fixed operator- (Fixed const & rhs) const; + Fixed operator* (Fixed const & rhs) const; + Fixed operator/ (Fixed const & rhs) const; + Fixed & operator++(void); // prefix ++o + Fixed & operator--(void); // prefix --o + Fixed operator++(int); // postfix o++ + Fixed operator--(int); // postfix o-- + + static const Fixed & min(Fixed const & lhs, Fixed const & rhs); + static const Fixed & max(Fixed const & lhs, Fixed const & rhs); + static Fixed & min(Fixed & lhs, Fixed & rhs); + static Fixed & max(Fixed & lhs, Fixed & rhs); + + int getRawBits(void) const; + void setRawBits(int const raw); + float toFloat(void) const; + int toInt(void) const; + +private: + + int _value; + static int const _frac; + static int const _max; + static int const _min; + +}; + +std::ostream & operator<<(std::ostream & o, Fixed const & rhs); + +#endif diff --git a/d07/ex00/Templates.hpp b/d07/ex00/headers/Templates.hpp similarity index 100% rename from d07/ex00/Templates.hpp rename to d07/ex00/headers/Templates.hpp diff --git a/d07/ex00/colors.h b/d07/ex00/headers/colors.h similarity index 100% rename from d07/ex00/colors.h rename to d07/ex00/headers/colors.h diff --git a/d07/ex00/main.cpp b/d07/ex00/main.cpp index 5e9683f..9401fd9 100644 --- a/d07/ex00/main.cpp +++ b/d07/ex00/main.cpp @@ -2,8 +2,27 @@ #include #include "colors.h" #include "Templates.hpp" +#include "Fixed.hpp" -#define N_TEST "3" +#define N_TEST "5" + +class Test { +public: + Test(int n = 0) : _n(n) {} + int getN() const {return _n;} + bool operator==(Test const & rhs) const {return (this->_n == rhs._n);} + bool operator!=(Test const & rhs) const {return (this->_n != rhs._n);} + bool operator> (Test const & rhs) const {return (this->_n > rhs._n);} + bool operator< (Test const & rhs) const {return (rhs._n > this->_n);} + bool operator>=(Test const & rhs) const {return ( !(this->_n < rhs._n) );} + bool operator<=(Test const & rhs) const {return ( !(this->_n > rhs._n) );} +private: + int _n; +}; +std::ostream & operator<<(std::ostream & o, Test const & rhs){ + o << rhs.getN(); + return (o); +} int main() { int i = 0; @@ -13,12 +32,13 @@ int main() { { int a = 2; int b = 3; - - std::cout << "a = " << a << ", b = " << b << "\nswap :\n"; + + std::cout << "a = " << a << ", b = " << b << "\n" B_BLUE "swap :" RESET "\n"; ::swap( a, b ); std::cout << "a = " << a << ", b = " << b << "\n"; - std::cout << "min( a, b ) = " << ::min( a, b ) << "\n"; - std::cout << "max( a, b ) = " << ::max( a, b ) << "\n"; + + std::cout << B_BLUE "min( a, b ) = " RESET << ::min( a, b ) << "\n"; + std::cout << B_BLUE "max( a, b ) = " RESET << ::max( a, b ) << "\n"; } std::cout << B_YELLOW "\n[" << ++i << "/" N_TEST "] " @@ -26,12 +46,13 @@ int main() { { std::string a = "chaine1"; std::string b = "chaine2"; - - std::cout << "a = " << a << ", b = " << b << "\nswap :\n"; + + std::cout << "a = " << a << ", b = " << b << "\n" B_BLUE "swap :" RESET "\n"; ::swap(a, b); std::cout << "a = " << a << ", b = " << b << "\n"; - std::cout << "min( a, b ) = " << ::min( a, b ) << "\n"; - std::cout << "max( a, b ) = " << ::max( a, b ) << "\n"; + + std::cout << B_BLUE "min( a, b ) = " RESET << ::min( a, b ) << "\n"; + std::cout << B_BLUE "max( a, b ) = " RESET << ::max( a, b ) << "\n"; } std::cout << B_YELLOW "\n[" << ++i << "/" N_TEST "] " @@ -39,12 +60,42 @@ int main() { { float a = 2.42f; float b = 32.7f; - - std::cout << "a = " << a << ", b = " << b << "\nswap :\n"; + + std::cout << "a = " << a << ", b = " << b << "\n" B_BLUE "swap :" RESET "\n"; ::swap( a, b ); std::cout << "a = " << a << ", b = " << b << "\n"; - std::cout << "min( a, b ) = " << ::min( a, b ) << "\n"; - std::cout << "max( a, b ) = " << ::max( a, b ) << "\n"; + + std::cout << B_BLUE "min( a, b ) = " RESET << ::min( a, b ) << "\n"; + std::cout << B_BLUE "max( a, b ) = " RESET << ::max( a, b ) << "\n"; + } + + std::cout << B_YELLOW "\n[" << ++i << "/" N_TEST "] " + << "tests fixed :" RESET "\n"; + { + Fixed a(2.42f); + Fixed b(32.7f); + + std::cout << "a = " << a << ", b = " << b << "\n" B_BLUE "swap :" RESET "\n"; + ::swap( a, b ); + std::cout << "a = " << a << ", b = " << b << "\n"; + + std::cout << B_BLUE "min( a, b ) = " RESET << ::min( a, b ) << "\n"; + std::cout << B_BLUE "max( a, b ) = " RESET << ::max( a, b ) << "\n"; + } + + std::cout << B_YELLOW "\n[" << ++i << "/" N_TEST "] " + << "tests class :" RESET "\n"; + { + + Test a(8); + Test b(16); + + std::cout << "a = " << a << ", b = " << b << "\n" B_BLUE "swap :" RESET "\n"; + ::swap( a, b ); + std::cout << "a = " << a << ", b = " << b << "\n"; + + std::cout << B_BLUE "min( a, b ) = " RESET << ::min( a, b ) << "\n"; + std::cout << B_BLUE "max( a, b ) = " RESET << ::max( a, b ) << "\n"; } return 0; diff --git a/d07/ex00/srcs/Fixed.cpp b/d07/ex00/srcs/Fixed.cpp new file mode 100644 index 0000000..3e72ea0 --- /dev/null +++ b/d07/ex00/srcs/Fixed.cpp @@ -0,0 +1,225 @@ +#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); +int const Fixed::_min = ~_max; + + +/* + * 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 < Fixed::_min || integer > Fixed::_max) + std::cout << "error: integer out of range" << '\n'; + else + this->_value = integer << Fixed::_frac; +} + +Fixed::Fixed(float const floater) { + if (floater < Fixed::_min || floater > Fixed::_max) + std::cout << "error: float out of range" << '\n'; + else + this->_value = roundf(floater * (1 << Fixed::_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->_value < rhs._value; +} +bool Fixed::operator> (Fixed const & rhs) const { + return rhs < *this; +} +bool Fixed::operator<=(Fixed const & rhs) const { + return !(*this > rhs); +} +bool Fixed::operator>=(Fixed const & rhs) const { + return !(*this < rhs); +} +bool Fixed::operator==(Fixed const & rhs) const { + return this->_value == rhs._value; +} +bool Fixed::operator!=(Fixed const & rhs) const { + return !(*this == rhs); +} +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); + result._value = ((long)result._value * (long)rhs._value) >> Fixed::_frac; + return result; +} +Fixed Fixed::operator/ ( Fixed const & rhs ) const { + Fixed result(*this); + if (rhs._value == 0) + std::cout << "!impossible division by 0¡"; + else + result._value = (long)(result._value << Fixed::_frac) / rhs._value; + return result; +} +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 >> Fixed::_frac); +} +float Fixed::toFloat( void ) const { + return ((float)this->_value / (float)(1 << Fixed::_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); +} diff --git a/d07/ex01/Fixed.cpp b/d07/ex01/Fixed.cpp new file mode 100644 index 0000000..3e72ea0 --- /dev/null +++ b/d07/ex01/Fixed.cpp @@ -0,0 +1,225 @@ +#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); +int const Fixed::_min = ~_max; + + +/* + * 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 < Fixed::_min || integer > Fixed::_max) + std::cout << "error: integer out of range" << '\n'; + else + this->_value = integer << Fixed::_frac; +} + +Fixed::Fixed(float const floater) { + if (floater < Fixed::_min || floater > Fixed::_max) + std::cout << "error: float out of range" << '\n'; + else + this->_value = roundf(floater * (1 << Fixed::_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->_value < rhs._value; +} +bool Fixed::operator> (Fixed const & rhs) const { + return rhs < *this; +} +bool Fixed::operator<=(Fixed const & rhs) const { + return !(*this > rhs); +} +bool Fixed::operator>=(Fixed const & rhs) const { + return !(*this < rhs); +} +bool Fixed::operator==(Fixed const & rhs) const { + return this->_value == rhs._value; +} +bool Fixed::operator!=(Fixed const & rhs) const { + return !(*this == rhs); +} +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); + result._value = ((long)result._value * (long)rhs._value) >> Fixed::_frac; + return result; +} +Fixed Fixed::operator/ ( Fixed const & rhs ) const { + Fixed result(*this); + if (rhs._value == 0) + std::cout << "!impossible division by 0¡"; + else + result._value = (long)(result._value << Fixed::_frac) / rhs._value; + return result; +} +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 >> Fixed::_frac); +} +float Fixed::toFloat( void ) const { + return ((float)this->_value / (float)(1 << Fixed::_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); +} diff --git a/d07/ex01/Makefile b/d07/ex01/Makefile index 50bc55b..efc01c9 100644 --- a/d07/ex01/Makefile +++ b/d07/ex01/Makefile @@ -29,14 +29,17 @@ LIBS = INCLUDES = -I$(D_HEADERS) D_SRCS = . -SRCS = main.cpp +SRCS = main.cpp \ + Fixed.cpp D_HEADERS = headers HEADERS = colors.h \ Iter.hpp \ Print.hpp \ ToUpper.hpp \ - Decrement.hpp + Decrement.hpp \ + ClassTest.hpp \ + Fixed.hpp D_OBJS = builds OBJS = $(SRCS:%.$(EXT)=$(D_OBJS)/%.o) diff --git a/d07/ex01/headers/ClassTest.hpp b/d07/ex01/headers/ClassTest.hpp new file mode 100644 index 0000000..4e3e1fd --- /dev/null +++ b/d07/ex01/headers/ClassTest.hpp @@ -0,0 +1,20 @@ +#ifndef CLASSTEST_HPP +# define CLASSTEST_HPP + +# include + +class ClassTest { +public: + ClassTest() : _value("hello") {} + std::string getValue() const {return _value;} +private: + std::string _value; +}; + +std::ostream & operator<<(std::ostream & o, ClassTest const & rhs) { + o << rhs.getValue(); + return o; +} + +#endif + diff --git a/d07/ex01/headers/Fixed.hpp b/d07/ex01/headers/Fixed.hpp new file mode 100644 index 0000000..b63a80c --- /dev/null +++ b/d07/ex01/headers/Fixed.hpp @@ -0,0 +1,55 @@ +#ifndef FIXED_HPP +# define FIXED_HPP + +#include +#include +#include + +class Fixed { + +public: + + Fixed(void); // default/parametric constructor + Fixed(Fixed const & src); // copy constructor + ~Fixed(void); // destructor + Fixed(int integer); + Fixed(float const floater); + + Fixed & operator= (Fixed const & rhs); // assignement operator + bool operator< (Fixed const & rhs) const; + bool operator> (Fixed const & rhs) const; + bool operator<=(Fixed const & rhs) const; + bool operator>=(Fixed const & rhs) const; + bool operator==(Fixed const & rhs) const; + bool operator!=(Fixed const & rhs) const; + Fixed operator+ (Fixed const & rhs) const; + Fixed operator- (Fixed const & rhs) const; + Fixed operator* (Fixed const & rhs) const; + Fixed operator/ (Fixed const & rhs) const; + Fixed & operator++(void); // prefix ++o + Fixed & operator--(void); // prefix --o + Fixed operator++(int); // postfix o++ + Fixed operator--(int); // postfix o-- + + static const Fixed & min(Fixed const & lhs, Fixed const & rhs); + static const Fixed & max(Fixed const & lhs, Fixed const & rhs); + static Fixed & min(Fixed & lhs, Fixed & rhs); + static Fixed & max(Fixed & lhs, Fixed & rhs); + + int getRawBits(void) const; + void setRawBits(int const raw); + float toFloat(void) const; + int toInt(void) const; + +private: + + int _value; + static int const _frac; + static int const _max; + static int const _min; + +}; + +std::ostream & operator<<(std::ostream & o, Fixed const & rhs); + +#endif diff --git a/d07/ex01/iter b/d07/ex01/iter new file mode 100755 index 0000000000000000000000000000000000000000..3116a3a2ccfa6baf8cfce69c1f8967a9762474cb GIT binary patch literal 25144 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 literal 0 HcmV?d00001 diff --git a/d07/ex01/main.cpp b/d07/ex01/main.cpp index 945b374..47c98ab 100644 --- a/d07/ex01/main.cpp +++ b/d07/ex01/main.cpp @@ -5,8 +5,10 @@ #include "Print.hpp" #include "ToUpper.hpp" #include "Decrement.hpp" +#include "ClassTest.hpp" +#include "Fixed.hpp" -#define N_TEST "2" +#define N_TEST "4" int main() { int i = 0; @@ -38,6 +40,22 @@ int main() { ::Iter(arr, len, Print); } + std::cout << B_YELLOW "\n[" << ++i << "/" N_TEST "] " + << "tests class :" RESET "\n"; + { + ClassTest tab[5]; + + ::Iter(tab, 5, Print); + } + + std::cout << B_YELLOW "\n[" << ++i << "/" N_TEST "] " + << "tests fixed :" RESET "\n"; + { + Fixed f[5]; + + ::Iter(f, 5, Print); + } + return 0; } diff --git a/d07/ex02/Fixed.cpp b/d07/ex02/Fixed.cpp new file mode 100644 index 0000000..3e72ea0 --- /dev/null +++ b/d07/ex02/Fixed.cpp @@ -0,0 +1,225 @@ +#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); +int const Fixed::_min = ~_max; + + +/* + * 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 < Fixed::_min || integer > Fixed::_max) + std::cout << "error: integer out of range" << '\n'; + else + this->_value = integer << Fixed::_frac; +} + +Fixed::Fixed(float const floater) { + if (floater < Fixed::_min || floater > Fixed::_max) + std::cout << "error: float out of range" << '\n'; + else + this->_value = roundf(floater * (1 << Fixed::_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->_value < rhs._value; +} +bool Fixed::operator> (Fixed const & rhs) const { + return rhs < *this; +} +bool Fixed::operator<=(Fixed const & rhs) const { + return !(*this > rhs); +} +bool Fixed::operator>=(Fixed const & rhs) const { + return !(*this < rhs); +} +bool Fixed::operator==(Fixed const & rhs) const { + return this->_value == rhs._value; +} +bool Fixed::operator!=(Fixed const & rhs) const { + return !(*this == rhs); +} +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); + result._value = ((long)result._value * (long)rhs._value) >> Fixed::_frac; + return result; +} +Fixed Fixed::operator/ ( Fixed const & rhs ) const { + Fixed result(*this); + if (rhs._value == 0) + std::cout << "!impossible division by 0¡"; + else + result._value = (long)(result._value << Fixed::_frac) / rhs._value; + return result; +} +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 >> Fixed::_frac); +} +float Fixed::toFloat( void ) const { + return ((float)this->_value / (float)(1 << Fixed::_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); +} diff --git a/d07/ex02/Makefile b/d07/ex02/Makefile index 2f18fa0..f1c973b 100644 --- a/d07/ex02/Makefile +++ b/d07/ex02/Makefile @@ -29,14 +29,16 @@ LIBS = INCLUDES = -I$(D_HEADERS) D_SRCS = . -SRCS = main.cpp +SRCS = main.cpp \ + Fixed.cpp D_HEADERS = headers HEADERS = colors.h \ Array.hpp \ Iter.hpp \ Print.hpp \ - Fill.hpp + Fill.hpp \ + Fixed.hpp D_OBJS = builds OBJS = $(SRCS:%.$(EXT)=$(D_OBJS)/%.o) diff --git a/d07/ex02/array b/d07/ex02/array new file mode 100755 index 0000000000000000000000000000000000000000..c5a5de6cbbcc03522d9bdb046b21a1ee8ba16c49 GIT binary patch literal 77664 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 literal 0 HcmV?d00001 diff --git a/d07/ex02/headers/Array.hpp b/d07/ex02/headers/Array.hpp index 1445e1c..804a784 100644 --- a/d07/ex02/headers/Array.hpp +++ b/d07/ex02/headers/Array.hpp @@ -6,11 +6,22 @@ template < typename T > class Array { public: - Array(unsigned int n = 0u) - : _size(n) - , _arr(new T[n]) {}; - ~Array() { delete [] _arr; }; - Array(Array const & src) : _arr(new T[0]) { *this = src; }; + Array(unsigned int n = 0U) + : _size(n) + , _arr(new T[n]){ + for (unsigned int i = 0; i < n; i++) + _arr[i] = 0; + }; + + ~Array() { + delete [] _arr; + }; + + Array(Array const & src) + : _arr(new T[0]) { + *this = src; + }; + Array &operator=(Array const & rhs) { if (this == &rhs) return (*this); diff --git a/d07/ex02/headers/Fixed.hpp b/d07/ex02/headers/Fixed.hpp new file mode 100644 index 0000000..b63a80c --- /dev/null +++ b/d07/ex02/headers/Fixed.hpp @@ -0,0 +1,55 @@ +#ifndef FIXED_HPP +# define FIXED_HPP + +#include +#include +#include + +class Fixed { + +public: + + Fixed(void); // default/parametric constructor + Fixed(Fixed const & src); // copy constructor + ~Fixed(void); // destructor + Fixed(int integer); + Fixed(float const floater); + + Fixed & operator= (Fixed const & rhs); // assignement operator + bool operator< (Fixed const & rhs) const; + bool operator> (Fixed const & rhs) const; + bool operator<=(Fixed const & rhs) const; + bool operator>=(Fixed const & rhs) const; + bool operator==(Fixed const & rhs) const; + bool operator!=(Fixed const & rhs) const; + Fixed operator+ (Fixed const & rhs) const; + Fixed operator- (Fixed const & rhs) const; + Fixed operator* (Fixed const & rhs) const; + Fixed operator/ (Fixed const & rhs) const; + Fixed & operator++(void); // prefix ++o + Fixed & operator--(void); // prefix --o + Fixed operator++(int); // postfix o++ + Fixed operator--(int); // postfix o-- + + static const Fixed & min(Fixed const & lhs, Fixed const & rhs); + static const Fixed & max(Fixed const & lhs, Fixed const & rhs); + static Fixed & min(Fixed & lhs, Fixed & rhs); + static Fixed & max(Fixed & lhs, Fixed & rhs); + + int getRawBits(void) const; + void setRawBits(int const raw); + float toFloat(void) const; + int toInt(void) const; + +private: + + int _value; + static int const _frac; + static int const _max; + static int const _min; + +}; + +std::ostream & operator<<(std::ostream & o, Fixed const & rhs); + +#endif diff --git a/d07/ex02/main.cpp b/d07/ex02/main.cpp index 20fd472..a00d3cf 100644 --- a/d07/ex02/main.cpp +++ b/d07/ex02/main.cpp @@ -7,8 +7,9 @@ #include "Print.hpp" #include "Array.hpp" #include "Fill.hpp" +#include "Fixed.hpp" -#define N_TEST "7" +#define N_TEST "13" int main() { srand(time(NULL)); @@ -91,15 +92,134 @@ int main() { std::cout << "\n"; } - // tests luke std::cout << B_YELLOW "\n[" << ++i << "/" N_TEST "] " - << "tests :" RESET "\n"; + << "tests simple array :" RESET "\n"; { Array a(10); std::cout << "a.size :" << a.size() << "\n"; } + std::cout << B_YELLOW "\n[" << ++i << "/" N_TEST "] " + << "tests empty array :" RESET "\n"; + { + Array arr(0); + + std::cout << "arr.size :" << arr.size() << "\n"; + try { + arr[arr.size()] = 42; } + catch(std::exception& e) { + std::cerr << e.what() << '\n'; } + } + + std::cout << B_YELLOW "\n[" << ++i << "/" N_TEST "] " + << "tests write and read :" RESET "\n"; + { + std::cout << B_BLUE "create Array arr(5);" RESET "\n"; + Array arr(5); + std::cout << B_BLUE "create Array const constarr(5);" RESET "\n"; + Array const constarr(5); + + std::cout << "arr.size :" << arr.size() << "\n"; + std::cout << "constarr.size :" << constarr.size() << "\n"; + + try { + std::cout << B_BLUE "arr[3] = 12" RESET "\n"; + arr[3] = 12; + std::cout << B_BLUE "print arr;" RESET "\n"; + ::Iter(arr, arr.size(), Print); + std::cout << "\n"; } + catch(std::exception& e) { + std::cerr << e.what() << '\n'; } + + try { + std::cout << B_BLUE "print constarr;" RESET "\n"; + ::Iter(constarr, constarr.size(), Print); + std::cout << "\n"; } + catch(std::exception& e) { + std::cerr << e.what() << '\n'; } + } + + std::cout << B_YELLOW "\n[" << ++i << "/" N_TEST "] " + << "tests empty Fixed array :" RESET "\n"; + { + Array arr(0); + + std::cout << "fixed arr.size :" << arr.size() << "\n"; + try { + arr[arr.size()] = 42; } + catch(std::exception& e) { + std::cerr << e.what() << '\n'; } + } + + std::cout << B_YELLOW "\n[" << ++i << "/" N_TEST "] " + << "tests fixed write and read :" RESET "\n"; + { + std::cout << B_BLUE "create Array arr(5);" RESET "\n"; + Array arr(5); + std::cout << B_BLUE "create Array const constarr(5);" RESET "\n"; + Array const constarr(5); + + std::cout << "arr.size :" << arr.size() << "\n"; + std::cout << "constarr.size :" << constarr.size() << "\n"; + + try { + std::cout << B_BLUE "arr[3] = 12" RESET "\n"; + arr[3] = 12; + std::cout << B_BLUE "print arr;" RESET "\n"; + ::Iter(arr, arr.size(), Print); + std::cout << "\n"; } + catch(std::exception& e) { + std::cerr << e.what() << '\n'; } + + try { + std::cout << B_BLUE "print constarr;" RESET "\n"; + ::Iter(constarr, constarr.size(), Print); + std::cout << "\n"; } + catch(std::exception& e) { + std::cerr << e.what() << '\n'; } + } + + std::cout << B_YELLOW "\n[" << ++i << "/" N_TEST "] " + << "tests empty Fixed array :" RESET "\n"; + { + Array arr(0); + + std::cout << "char arr.size :" << arr.size() << "\n"; + try { + arr[arr.size()] = 'c'; } + catch(std::exception& e) { + std::cerr << e.what() << '\n'; } + } + + std::cout << B_YELLOW "\n[" << ++i << "/" N_TEST "] " + << "tests char write and read :" RESET "\n"; + { + std::cout << B_BLUE "create Array arr(5);" RESET "\n"; + Array arr(5); + std::cout << B_BLUE "create Array const constarr(5);" RESET "\n"; + Array const constarr(5); + + std::cout << "arr.size :" << arr.size() << "\n"; + std::cout << "constarr.size :" << constarr.size() << "\n"; + + try { + std::cout << B_BLUE "arr[3] = 12" RESET "\n"; + arr[3] = 12; + std::cout << B_BLUE "print arr;" RESET "\n"; + ::Iter(arr, arr.size(), Print); + std::cout << "\n"; } + catch(std::exception& e) { + std::cerr << e.what() << '\n'; } + + try { + std::cout << B_BLUE "print constarr;" RESET "\n"; + ::Iter(constarr, constarr.size(), Print); + std::cout << "\n"; } + catch(std::exception& e) { + std::cerr << e.what() << '\n'; } + } + std::cout << B_YELLOW "\n[" << ++i << "/" N_TEST "] " << "tests index correct :" RESET "\n"; { @@ -141,7 +261,7 @@ int main() { } std::cout << B_YELLOW "\n[" << ++i << "/" N_TEST "] " - << "tests :" RESET "\n"; + << "tests subject :" RESET "\n"; { #define MAX_VAL 750 Array numbers(MAX_VAL);