d06 ex00 ajout qq tests avec limits des floats

This commit is contained in:
hugogogo
2022-03-10 16:14:01 +01:00
parent 04dea6722f
commit 31c9d8af06
10 changed files with 161 additions and 58 deletions

View File

@@ -34,7 +34,8 @@ SRCS = main.cpp \
checkChar.cpp \ checkChar.cpp \
checkInt.cpp \ checkInt.cpp \
checkFloat.cpp \ checkFloat.cpp \
checkDouble.cpp checkDouble.cpp \
toTypes.cpp
D_HEADERS = . D_HEADERS = .
HEADERS = convert.h HEADERS = convert.h

BIN
d06/ex00/a.out Executable file

Binary file not shown.

Binary file not shown.

View File

@@ -17,6 +17,14 @@ bool checkInt(std::string str);
bool checkFloat(std::string str); bool checkFloat(std::string str);
bool checkDouble(std::string str); bool checkDouble(std::string str);
// templates
// see : https://isocpp.org/wiki/faq/templates#templates-defn-vs-decl
template <typename T> void toChar(T value);
template <typename T> void toInt(T value);
template <typename T> void toFloat(T value);
template <typename T> void toDouble(T value);
//template <typename T> void printDot(T value);
#define MAX_INT "2147483647" #define MAX_INT "2147483647"
#define MIN_INT "-2147483648" #define MIN_INT "-2147483648"
#define MAX_INT_1 "2147483648" #define MAX_INT_1 "2147483648"
@@ -24,6 +32,7 @@ bool checkDouble(std::string str);
#define INT_MAX_LENGTH 10 #define INT_MAX_LENGTH 10
#define MAX_FLOAT_INT_PRECISION "16777216" #define MAX_FLOAT_INT_PRECISION "16777216"
#define MAX_FLOAT "340282346638528859811704183484516925440" #define MAX_FLOAT "340282346638528859811704183484516925440"
#define MIN_FLOAT "-340282346638528859811704183484516925440"
#define FLOAT_MAX_LENGTH 39 #define FLOAT_MAX_LENGTH 39
#define MAX_DOUBLE "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368" #define MAX_DOUBLE "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368"
#define DOUBLE_MAX_LENGTH 309 #define DOUBLE_MAX_LENGTH 309
@@ -49,6 +58,7 @@ bool checkDouble(std::string str);
#define MAX_F_4 "340282346638528859811704183484516925444" #define MAX_F_4 "340282346638528859811704183484516925444"
#define MAX_F_5 "340282346638528859811704183484516925445" #define MAX_F_5 "340282346638528859811704183484516925445"
#define MAX_F_6 "340282346638528859811704183484516925446" #define MAX_F_6 "340282346638528859811704183484516925446"
#define MAX_F_N "340282346638528897590636046441678635008"
#define MIN_DOUBLE "-179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368" #define MIN_DOUBLE "-179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368"
#define MAX_D__1 "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858367" #define MAX_D__1 "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858367"
#define MAX_D__2 "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858366" #define MAX_D__2 "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858366"

View File

@@ -180,6 +180,7 @@ int main(int ac, char **av) {
convert(MAX_F_4".0f"); convert(MAX_F_4".0f");
convert(MAX_F_5".0f"); convert(MAX_F_5".0f");
convert(MAX_F_6".0f"); convert(MAX_F_6".0f");
convert(MAX_F_N".0f");
//double //double
convert("0.0"); convert("0.0");
convert("-4.2"); convert("-4.2");
@@ -213,6 +214,7 @@ int main(int ac, char **av) {
convert(MAX_F_4".0"); convert(MAX_F_4".0");
convert(MAX_F_5".0"); convert(MAX_F_5".0");
convert(MAX_F_6".0"); convert(MAX_F_6".0");
convert(MAX_F_N".0");
convert(MAX_DOUBLE".0"); convert(MAX_DOUBLE".0");
convert(MIN_DOUBLE".0"); convert(MIN_DOUBLE".0");
convert(MAX_D__1".0"); convert(MAX_D__1".0");

View File

@@ -2,29 +2,11 @@
void fromDouble(double value) { void fromDouble(double value) {
// char // char
std::cout << std::setw(7) << std::left << "char"; toChar(value);
if (value < 0 || value > std::numeric_limits<char>::max())
std::cout << B_RED << "impossible" << RESET "\n";
else if (!isprint(value))
std::cout << B_RED << "non displayable" << RESET "\n";
else
std::cout << B_CYAN << static_cast<char>(value) << RESET "\n";
// int // int
std::cout << std::setw(7) << std::left << "int"; toInt(value);
if (value < std::numeric_limits<int>::min()
|| value > std::numeric_limits<int>::max() )
std::cout << B_RED << "impossible" << RESET "\n";
else
std::cout << B_CYAN << static_cast<int>(value) << RESET "\n";
// float // float
std::cout << std::setw(7) << std::left << "float"; toFloat(value);
if (value < std::numeric_limits<float>::min()
|| value > std::numeric_limits<float>::max() )
std::cout << B_RED << "impossible" << RESET "\n";
else
std::cout << B_CYAN << static_cast<double>(value) << RESET "\n";
} }
bool isDouble(std::string str) { bool isDouble(std::string str) {
@@ -57,8 +39,11 @@ bool checkDouble(std::string str) {
if (!isDouble(str)) if (!isDouble(str))
return false; return false;
std::istringstream(str) >> d; // std::istringstream(str) >> d;
std::cout << B_CYAN << d << B_YELLOW " double" RESET "\n"; d = strtod(str.c_str(), NULL);
std::cout << std::fixed << B_CYAN << d;
// printDot(d);
std::cout << B_YELLOW " double" RESET "\n";
fromDouble(d); fromDouble(d);
return true; return true;

View File

@@ -1,29 +1,15 @@
#include "convert.h" #include "convert.h"
void fromFloat(float value) { static void fromFloat(float value) {
// char // char
std::cout << std::setw(7) << std::left << "char"; toChar(value);
if (value < 0 || value > std::numeric_limits<char>::max())
std::cout << B_RED << "impossible" << RESET "\n";
else if (!isprint(value))
std::cout << B_RED << "non displayable" << RESET "\n";
else
std::cout << B_CYAN << static_cast<char>(value) << RESET "\n";
// int // int
std::cout << std::setw(7) << std::left << "int"; toInt(value);
if (value < std::numeric_limits<int>::min()
|| value > std::numeric_limits<int>::max() )
std::cout << B_RED << "impossible" << RESET "\n";
else
std::cout << B_CYAN << static_cast<int>(value) << RESET "\n";
// double // double
std::cout << std::setw(7) << std::left << "double"; toDouble(value);
std::cout << B_CYAN << static_cast<double>(value) << RESET "\n";
} }
bool isFloat(std::string str) { static bool isFloat(std::string str) {
size_t l; size_t l;
size_t l2; size_t l2;
@@ -53,8 +39,11 @@ bool checkFloat(std::string str) {
if (!isFloat(str)) if (!isFloat(str))
return false; return false;
std::istringstream(str) >> f; // std::istringstream(str) >> f;
std::cout << B_CYAN << f << B_YELLOW " float" RESET "\n"; f = strtod(str.c_str(), NULL);
std::cout << std::fixed << B_CYAN << f;
// printDot(f);
std::cout << "f" << B_YELLOW " float" RESET "\n";
fromFloat(f); fromFloat(f);
return true; return true;

View File

@@ -2,21 +2,11 @@
void fromInt(int value) { void fromInt(int value) {
// char // char
std::cout << std::setw(7) << std::left << "char"; toChar(value);
if (value < 0 || value > std::numeric_limits<char>::max())
std::cout << B_RED << "impossible" << RESET "\n";
else if (!isprint(value))
std::cout << B_RED << "non displayable" << RESET "\n";
else
std::cout << B_CYAN << static_cast<char>(value) << RESET "\n";
// float // float
std::cout << std::setw(7) << std::left << "float" << B_CYAN toFloat(value);
<< static_cast<float>(value) << RESET "\n";
// double // double
std::cout << std::setw(7) << std::left << "double" << B_CYAN toDouble(value);
<< static_cast<double>(value) << RESET "\n";
} }
bool isInt(std::string str) { bool isInt(std::string str) {

90
d06/ex00/srcs/toTypes.cpp Normal file
View File

@@ -0,0 +1,90 @@
#include "convert.h"
#include <cfloat>
// tried to check for NaN and INF
//static bool is_inf_pos( float a ) { return ( *(((long*)(&a))+1) & 0xFFFFFFFFU ) == 0x7F800000U; }
//static bool is_inf_neg( float a ) { return ( *(((long*)(&a))+1) & 0xFFFFFFFFU ) == 0xFF800000U; }
//static bool is_nan( float a ) { return (( *(((long*)(&a))+1) & 0x7FF80000L ) == 0x7FF800000L); }
// https://isocpp.org/wiki/faq/templates#templates-defn-vs-decl
template <typename T>
void toChar(T value) {
std::cout << std::setw(7) << std::left << "char";
// if (value < 0 || value > std::numeric_limits<char>::max())
if (!(value >= 0 && value <= std::numeric_limits<char>::max()))
std::cout << B_RED << "impossible" << RESET "\n";
else if (!isprint(value))
std::cout << B_RED << "non displayable" << RESET "\n";
else
std::cout << B_CYAN << static_cast<char>(value) << RESET "\n";
}
template <typename T>
void toInt(T value) {
std::cout << std::setw(7) << std::left << "int";
// if (value < std::numeric_limits<int>::min()
// || value > std::numeric_limits<int>::max() )
if (! (value <= std::numeric_limits<int>::max()
&& value >= std::numeric_limits<int>::min()) )
{
std::cout << B_RED << "impossible" << RESET "\n";
return ;
}
std::cout << B_CYAN << static_cast<int>(value) << RESET "\n";
}
template <typename T>
void toFloat(T value) {
std::cout << std::setw(7) << std::left << "float";
// tricks to check if is nan and infinity
// see : https://www.jacksondunstan.com/articles/983
// and : https://stackoverflow.com/questions/2249110/how-do-i-make-a-portable-isnan-isinf-function
if (!((value * 0) != 0))
// min() ne renvoit que 0, il faut utiliser lowest() (c++11) ou -max()
// https://stackoverflow.com/questions/17070351/why-does-numeric-limitsmin-return-a-negative-value-for-int-but-positive-values
// https://en.cppreference.com/w/cpp/types/numeric_limits/min
if (! (value <= std::numeric_limits<float>::max()
&& value >= -(std::numeric_limits<float>::max())) )
{
std::cout << B_RED << "impossible" << RESET "\n";
return ;
}
std::cout << B_CYAN << std::fixed << static_cast<float>(value);
// printDot(value);
std::cout << "f" << RESET "\n";
}
template <typename T>
void toDouble(T value) {
std::cout << std::setw(7) << std::left << "double" << B_CYAN
<< std::fixed << static_cast<double>(value);
// printDot(value);
std::cout << RESET "\n";
}
//template <typename T>
//void printDot(T value) {
// std::ostringstream ostr;
// ostr << value;
// if (ostr.str().compare("inf")
// && ostr.str().compare("-inf")
// && ostr.str().compare("nan"))
// if ((ostr.str().find('.')) == std::string::npos)
// std::cout << ".0";
//}
template void toChar<int>(int);
template void toChar<float>(float);
template void toChar<double>(double);
template void toInt<float>(float);
template void toInt<double>(double);
template void toFloat<int>(int);
template void toFloat<double>(double);
template void toDouble<int>(int);
template void toDouble<float>(float);
//template void printDot<float>(float);
//template void printDot<double>(double);

36
d06/ex00/test_float.cpp Normal file
View File

@@ -0,0 +1,36 @@
#include <iostream>
#include <limits>
#include <cfloat>
#include <cmath>
#define MAX_INT 2147483647
#define MIN_INT -2147483648
#define MAX_FLOAT 340282346638528859811704183484516925440.0f
#define MIN_FLOAT -340282346638528859811704183484516925440.0f
void isFloat(double d) {
if (! (d <= std::numeric_limits<float>::max()
&& d >= std::numeric_limits<float>::min()) )
{
std::cout << d << "is outside range of floats\n";
return ;
}
std::cout << std::fixed << static_cast<float>(d) << "\n";
}
int main() {
double d;
double d2;
d = std::numeric_limits<float>::max();
std::cout << std::fixed << d << "\n";
d2 = std::nextafter(d, DBL_MAX);
std::cout << std::fixed << d2 << "\n";
// isFloat(MAX_FLOAT);
// d = std::numeric_limits<float>::lowest();
// std::cout << std::fixed << d << "\n";
// isFloat(d);
return 0;
}