#include "multi_converter_units.h" #define MULTI_CONVERTER_CHAR_OVERFLOW '#' #define MULTI_CONVERTER_MAX_SUPORTED_INT 999999999 #define multi_converter_unit_set_overflow(b) \ for(int _i = 0; _i < MULTI_CONVERTER_NUMBER_DIGITS; _i++) \ b[_i] = MULTI_CONVERTER_CHAR_OVERFLOW; // // DEC / HEX / BIN conversion // void multi_converter_unit_dec_hex_bin_convert(MultiConverterState* const multi_converter_state) { char dest[MULTI_CONVERTER_NUMBER_DIGITS]; int i = 0; uint8_t overflow = 0; int a = 0; int r = 0; uint8_t f = 1; switch(multi_converter_state->unit_type_orig) { default: break; case UnitTypeDec: { a = atoi(multi_converter_state->buffer_orig); f = (multi_converter_state->unit_type_dest == UnitTypeHex ? 16 : 2); break; } case UnitTypeHex: a = strtol(multi_converter_state->buffer_orig, NULL, 16); f = (multi_converter_state->unit_type_dest == UnitTypeDec ? 10 : 2); break; case UnitTypeBin: a = strtol(multi_converter_state->buffer_orig, NULL, 2); f = (multi_converter_state->unit_type_dest == UnitTypeDec ? 10 : 16); break; } while(a > 0) { r = a % f; dest[i] = r + (r < 10 ? '0' : ('A' - 10)); a /= f; if(i++ >= MULTI_CONVERTER_NUMBER_DIGITS) { overflow = 1; break; } } if(overflow) { multi_converter_unit_set_overflow(multi_converter_state->buffer_dest); } else { // copy DEST (reversed) to destination and append empty chars at the end for(int j = 0; j < MULTI_CONVERTER_NUMBER_DIGITS; j++) { if(i >= 1) multi_converter_state->buffer_dest[j] = dest[--i]; else multi_converter_state->buffer_dest[j] = ' '; } } } uint8_t multi_converter_unit_dec_hex_bin_allowed(MultiConverterUnitType unit_type) { return (unit_type == UnitTypeDec || unit_type == UnitTypeHex || unit_type == UnitTypeBin); } // // CEL / FAR / KEL // void multi_converter_unit_temperature_convert(MultiConverterState* const multi_converter_state) { double a = strtof(multi_converter_state->buffer_orig, NULL); uint8_t overflow = 0; switch(multi_converter_state->unit_type_orig) { default: break; case UnitTypeCelsius: if(multi_converter_state->unit_type_dest == UnitTypeFahernheit) { // celsius to fahrenheit a = (a * ((double)1.8)) + 32; } else { // UnitTypeKelvin a += ((double)273.15); } break; case UnitTypeFahernheit: // fahrenheit to celsius, always a = (a - 32) / ((double)1.8); if(multi_converter_state->unit_type_dest == UnitTypeKelvin) { // if kelvin, add a += ((double)273.15); } break; case UnitTypeKelvin: // kelvin to celsius, always a -= ((double)273.15); if(multi_converter_state->unit_type_dest == UnitTypeFahernheit) { // if fahernheit, convert a = (a * ((double)1.8)) + 32; } break; } if(overflow) { multi_converter_unit_set_overflow(multi_converter_state->buffer_dest); } else { int ret = snprintf( multi_converter_state->buffer_dest, MULTI_CONVERTER_NUMBER_DIGITS + 1, "%.3lf", a); if(ret < 0) multi_converter_unit_set_overflow(multi_converter_state->buffer_dest); } } uint8_t multi_converter_unit_temperature_allowed(MultiConverterUnitType unit_type) { return ( unit_type == UnitTypeCelsius || unit_type == UnitTypeFahernheit || unit_type == UnitTypeKelvin); } // // KM / M / CM / MILES / FEET / INCHES // void multi_converter_unit_distance_convert(MultiConverterState* const multi_converter_state) { double a = strtof(multi_converter_state->buffer_orig, NULL); uint8_t overflow = 0; switch(multi_converter_state->unit_type_orig) { default: break; case UnitTypeKilometers: if(multi_converter_state->unit_type_dest == UnitTypeMeters) a *= ((double)1000); else if(multi_converter_state->unit_type_dest == UnitTypeCentimeters) a *= ((double)100000); else if(multi_converter_state->unit_type_dest == UnitTypeMiles) a *= ((double)0.6213711); else if(multi_converter_state->unit_type_dest == UnitTypeFeet) a *= ((double)3280.839895013); else if(multi_converter_state->unit_type_dest == UnitTypeInches) a *= ((double)39370.078740157); break; case UnitTypeMeters: if(multi_converter_state->unit_type_dest == UnitTypeKilometers) a /= ((double)1000); else if(multi_converter_state->unit_type_dest == UnitTypeCentimeters) a *= ((double)100); else if(multi_converter_state->unit_type_dest == UnitTypeMiles) a *= ((double)0.0006213711); else if(multi_converter_state->unit_type_dest == UnitTypeFeet) a *= ((double)3.280839895013); else if(multi_converter_state->unit_type_dest == UnitTypeInches) a *= ((double)39.370078740157); break; case UnitTypeCentimeters: if(multi_converter_state->unit_type_dest == UnitTypeKilometers) a /= ((double)100000); else if(multi_converter_state->unit_type_dest == UnitTypeMeters) a /= ((double)100); else if(multi_converter_state->unit_type_dest == UnitTypeMiles) a *= ((double)0.000006213711); else if(multi_converter_state->unit_type_dest == UnitTypeFeet) a *= ((double)0.03280839895013); else if(multi_converter_state->unit_type_dest == UnitTypeInches) a *= ((double)0.39370078740157); break; case UnitTypeMiles: if(multi_converter_state->unit_type_dest == UnitTypeKilometers) a *= ((double)1.609344); else if(multi_converter_state->unit_type_dest == UnitTypeMeters) a *= ((double)1609.344); else if(multi_converter_state->unit_type_dest == UnitTypeCentimeters) a *= ((double)160934.4); else if(multi_converter_state->unit_type_dest == UnitTypeFeet) a *= ((double)5280); else if(multi_converter_state->unit_type_dest == UnitTypeInches) a *= ((double)63360); break; case UnitTypeFeet: if(multi_converter_state->unit_type_dest == UnitTypeKilometers) a *= ((double)0.0003048); else if(multi_converter_state->unit_type_dest == UnitTypeMeters) a *= ((double)0.3048); else if(multi_converter_state->unit_type_dest == UnitTypeCentimeters) a *= ((double)30.48); else if(multi_converter_state->unit_type_dest == UnitTypeMiles) a *= ((double)0.000189393939394); else if(multi_converter_state->unit_type_dest == UnitTypeInches) a *= ((double)12); break; case UnitTypeInches: if(multi_converter_state->unit_type_dest == UnitTypeKilometers) a *= ((double)0.0000254); else if(multi_converter_state->unit_type_dest == UnitTypeMeters) a *= ((double)0.0254); else if(multi_converter_state->unit_type_dest == UnitTypeCentimeters) a *= ((double)2.54); else if(multi_converter_state->unit_type_dest == UnitTypeMiles) a *= ((double)0.0000157828282828); else if(multi_converter_state->unit_type_dest == UnitTypeFeet) a *= ((double)0.0833333333333); break; } if(overflow) { multi_converter_unit_set_overflow(multi_converter_state->buffer_dest); } else { int ret = snprintf( multi_converter_state->buffer_dest, MULTI_CONVERTER_NUMBER_DIGITS + 1, "%lf", a); if(ret < 0) multi_converter_unit_set_overflow(multi_converter_state->buffer_dest); } } uint8_t multi_converter_unit_distance_allowed(MultiConverterUnitType unit_type) { return ( unit_type == UnitTypeKilometers || unit_type == UnitTypeMeters || unit_type == UnitTypeCentimeters || unit_type == UnitTypeMiles || unit_type == UnitTypeFeet || unit_type == UnitTypeInches); } // // DEG / RAD // void multi_converter_unit_angle_convert(MultiConverterState* const multi_converter_state) { double a = strtof(multi_converter_state->buffer_orig, NULL); uint8_t overflow = 0; switch(multi_converter_state->unit_type_orig) { default: break; case UnitTypeDegree: if(multi_converter_state->unit_type_dest == UnitTypeRadian) a *= ((double)0.0174532925199); break; case UnitTypeRadian: if(multi_converter_state->unit_type_dest == UnitTypeDegree) a *= ((double)57.2957795131); break; } if(overflow) { multi_converter_unit_set_overflow(multi_converter_state->buffer_dest); } else { int ret = snprintf( multi_converter_state->buffer_dest, MULTI_CONVERTER_NUMBER_DIGITS + 1, "%lf", a); if(ret < 0) multi_converter_unit_set_overflow(multi_converter_state->buffer_dest); } } uint8_t multi_converter_unit_angle_allowed(MultiConverterUnitType unit_type) { return (unit_type == UnitTypeDegree || unit_type == UnitTypeRadian); }