#include #include #include #include #include #include #include enum Type { CHAR, INT, FLOAT, DOUBLE, INVALID }; static Type getType(const std::string& input) { if (input.length() == 1 && !std::isdigit(static_cast(input[0]))) return CHAR; if (input == "nanf" || input == "+inff" || input == "-inff") return FLOAT; if (input == "nan" || input == "+inf" || input == "-inf" || input == "inf") return DOUBLE; const size_t length = input.length(); if (length > 1 && (input[length - 1] == 'f' || input[length - 1] == 'F')) { char* end; std::strtod(input.c_str(), &end); if (end == input.c_str() + length - 1) return FLOAT; } char* end; errno = 0; std::strtol(input.c_str(), &end, 10); if (end == input.c_str() + length && errno != ERANGE) return INT; std::strtod(input.c_str(), &end); if (end == input.c_str() + length) return DOUBLE; return INVALID; } // ─── Parsing ──────────────────────────────────────────────────────────────── static char parseChar(const std::string& input) { return input[0]; } static long parseLong(const std::string& input) { return static_cast(std::strtol(input.c_str(), NULL, 10)); } static float parseFloat(const std::string& input) { if (input == "nanf") return std::numeric_limits::quiet_NaN(); if (input == "+inff") return std::numeric_limits::infinity(); if (input == "-inff") return -std::numeric_limits::infinity(); return static_cast(std::strtod(input.c_str(), NULL)); } static double parseDouble(const std::string& input) { if (input == "nan") return std::numeric_limits::quiet_NaN(); if (input == "+inf") return std::numeric_limits::infinity(); if (input == "-inf") return -std::numeric_limits::infinity(); if (input == "inf") return std::numeric_limits::infinity(); return static_cast(std::strtod(input.c_str(), NULL)); } // ─── Printing ─────────────────────────────────────────────────────────────── static bool isNan(const float f) { return f != f; } static bool isNan(const double d) { return d != d; } static bool isInf(const float f) { return f == std::numeric_limits::infinity() || f == -std::numeric_limits::infinity(); } static bool isInf(const double d) { return d == std::numeric_limits::infinity() || d == -std::numeric_limits::infinity(); } static void printChar(const char c) { if (std::isprint(static_cast(c))) std::cout << "'" << c << "'"; else std::cout << "Non displayable"; } static void printChar(const long l) { if (l < std::numeric_limits::min() || l > std::numeric_limits::max()) std::cout << "impossible"; else printChar(static_cast(l)); } static void printChar(const float f) { if (isNan(f) || isInf(f) || f < std::numeric_limits::min() || f > std::numeric_limits::max()) std::cout << "impossible"; else printChar(static_cast(f)); } static void printChar(const double d) { if (isNan(d) || isInf(d) || d < std::numeric_limits::min() || d > std::numeric_limits::max()) std::cout << "impossible"; else printChar(static_cast(d)); } static void printInt(const char c) { std::cout << static_cast(c); } static void printInt(const long l) { if (l < std::numeric_limits::min() || l > std::numeric_limits::max()) std::cout << "impossible"; else std::cout << static_cast(l); } static void printInt(const float f) { if (isNan(f) || isInf(f) || f < static_cast(std::numeric_limits::min()) || f > static_cast(std::numeric_limits::max())) std::cout << "impossible"; else std::cout << static_cast(f); } static void printInt(const double d) { if (isNan(d) || isInf(d) || d < std::numeric_limits::min() || d > std::numeric_limits::max()) std::cout << "impossible"; else std::cout << static_cast(d); } static void printFloat(const char c) { std::cout << static_cast(c) << 'f'; } static void printFloat(const long l) { if (static_cast(l) > std::numeric_limits::max() || static_cast(l) < -std::numeric_limits::max()) std::cout << "impossible"; else std::cout << static_cast(l) << 'f'; } static void printFloat(const float f) { if (isNan(f)) std::cout << "nanf"; else if (isInf(f)) std::cout << (f > 0 ? "+inff" : "-inff"); else std::cout << f << 'f'; } static void printFloat(const double d) { if (isNan(d)) std::cout << "nanf"; else if (isInf(d)) std::cout << (d > 0 ? "+inff" : "-inff"); else if (d > std::numeric_limits::max() || d < -std::numeric_limits::max()) std::cout << "impossible"; else std::cout << static_cast(d) << 'f'; } static void printDouble(const char c) { std::cout << static_cast(c); } static void printDouble(const long l) { std::cout << static_cast(l); } static void printDouble(const float f) { std::cout << static_cast(f); } static void printDouble(const double d) { if (isNan(d)) std::cout << "nan"; else if (isInf(d)) std::cout << (d > 0 ? "+inf" : "-inf"); else std::cout << d; } // ─── Conversion ───────────────────────────────────────────────────────────── void ScalarConverter::convert(const std::string& input) { std::cout << std::setprecision(1) << std::fixed; const Type type = getType(input); std::cout << "type : "; switch (type) { case CHAR: std::cout << "CHAR"; break; case INT: std::cout << "INT"; break; case FLOAT: std::cout << "FLOAT"; break; case DOUBLE: std::cout << "DOUBLE"; break; case INVALID: std::cout << "INVALID"; break; } std::cout << std::endl; std::cout << "char : "; switch (type) { case CHAR: printChar(parseChar(input)); break; case INT: printChar(parseLong(input)); break; case FLOAT: printChar(parseFloat(input)); break; case DOUBLE: printChar(parseDouble(input)); break; case INVALID: std::cout << "impossible"; break; } std::cout << std::endl; std::cout << "int : "; switch (type) { case CHAR: printInt(parseChar(input)); break; case INT: printInt(parseLong(input)); break; case FLOAT: printInt(parseFloat(input)); break; case DOUBLE: printInt(parseDouble(input)); break; case INVALID: std::cout << "impossible"; break; } std::cout << std::endl; std::cout << "float : "; switch (type) { case CHAR: printFloat(parseChar(input)); break; case INT: printFloat(parseLong(input)); break; case FLOAT: printFloat(parseFloat(input)); break; case DOUBLE: printFloat(parseDouble(input)); break; case INVALID: std::cout << "impossible"; break; } std::cout << std::endl; std::cout << "double: "; switch (type) { case CHAR: printDouble(parseChar(input)); break; case INT: printDouble(parseLong(input)); break; case FLOAT: printDouble(parseFloat(input)); break; case DOUBLE: printDouble(parseDouble(input)); break; case INVALID: std::cout << "impossible"; break; } std::cout << std::endl; }