multi_converter_units.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. #include "multi_converter_units.h"
  2. #define MULTI_CONVERTER_CHAR_OVERFLOW '#'
  3. #define MULTI_CONVERTER_MAX_SUPORTED_INT 999999999
  4. #define multi_converter_unit_set_overflow(b) \
  5. for(int _i = 0; _i < MULTI_CONVERTER_NUMBER_DIGITS; _i++) \
  6. b[_i] = MULTI_CONVERTER_CHAR_OVERFLOW;
  7. //
  8. // DEC / HEX / BIN conversion
  9. //
  10. void multi_converter_unit_dec_hex_bin_convert(MultiConverterState* const multi_converter_state) {
  11. char dest[MULTI_CONVERTER_NUMBER_DIGITS];
  12. int i = 0;
  13. uint8_t overflow = 0;
  14. int a = 0;
  15. int r = 0;
  16. uint8_t f = 1;
  17. switch(multi_converter_state->unit_type_orig) {
  18. default:
  19. break;
  20. case UnitTypeDec: {
  21. a = atoi(multi_converter_state->buffer_orig);
  22. f = (multi_converter_state->unit_type_dest == UnitTypeHex ? 16 : 2);
  23. break;
  24. }
  25. case UnitTypeHex:
  26. a = strtol(multi_converter_state->buffer_orig, NULL, 16);
  27. f = (multi_converter_state->unit_type_dest == UnitTypeDec ? 10 : 2);
  28. break;
  29. case UnitTypeBin:
  30. a = strtol(multi_converter_state->buffer_orig, NULL, 2);
  31. f = (multi_converter_state->unit_type_dest == UnitTypeDec ? 10 : 16);
  32. break;
  33. }
  34. while(a > 0) {
  35. r = a % f;
  36. dest[i] = r + (r < 10 ? '0' : ('A' - 10));
  37. a /= f;
  38. if(i++ >= MULTI_CONVERTER_NUMBER_DIGITS) {
  39. overflow = 1;
  40. break;
  41. }
  42. }
  43. if(overflow) {
  44. multi_converter_unit_set_overflow(multi_converter_state->buffer_dest);
  45. } else {
  46. // copy DEST (reversed) to destination and append empty chars at the end
  47. for(int j = 0; j < MULTI_CONVERTER_NUMBER_DIGITS; j++) {
  48. if(i >= 1)
  49. multi_converter_state->buffer_dest[j] = dest[--i];
  50. else
  51. multi_converter_state->buffer_dest[j] = ' ';
  52. }
  53. }
  54. }
  55. uint8_t multi_converter_unit_dec_hex_bin_allowed(MultiConverterUnitType unit_type) {
  56. return (unit_type == UnitTypeDec || unit_type == UnitTypeHex || unit_type == UnitTypeBin);
  57. }
  58. //
  59. // CEL / FAR / KEL
  60. //
  61. void multi_converter_unit_temperature_convert(MultiConverterState* const multi_converter_state) {
  62. double a = strtof(multi_converter_state->buffer_orig, NULL);
  63. uint8_t overflow = 0;
  64. switch(multi_converter_state->unit_type_orig) {
  65. default:
  66. break;
  67. case UnitTypeCelsius:
  68. if(multi_converter_state->unit_type_dest == UnitTypeFahernheit) {
  69. // celsius to fahrenheit
  70. a = (a * ((double)1.8)) + 32;
  71. } else { // UnitTypeKelvin
  72. a += ((double)273.15);
  73. }
  74. break;
  75. case UnitTypeFahernheit:
  76. // fahrenheit to celsius, always
  77. a = (a - 32) / ((double)1.8);
  78. if(multi_converter_state->unit_type_dest == UnitTypeKelvin) {
  79. // if kelvin, add
  80. a += ((double)273.15);
  81. }
  82. break;
  83. case UnitTypeKelvin:
  84. // kelvin to celsius, always
  85. a -= ((double)273.15);
  86. if(multi_converter_state->unit_type_dest == UnitTypeFahernheit) {
  87. // if fahernheit, convert
  88. a = (a * ((double)1.8)) + 32;
  89. }
  90. break;
  91. }
  92. if(overflow) {
  93. multi_converter_unit_set_overflow(multi_converter_state->buffer_dest);
  94. } else {
  95. int ret = snprintf(
  96. multi_converter_state->buffer_dest, MULTI_CONVERTER_NUMBER_DIGITS + 1, "%.3lf", a);
  97. if(ret < 0) multi_converter_unit_set_overflow(multi_converter_state->buffer_dest);
  98. }
  99. }
  100. uint8_t multi_converter_unit_temperature_allowed(MultiConverterUnitType unit_type) {
  101. return (
  102. unit_type == UnitTypeCelsius || unit_type == UnitTypeFahernheit ||
  103. unit_type == UnitTypeKelvin);
  104. }
  105. //
  106. // KM / M / CM / MILES / FEET / INCHES
  107. //
  108. void multi_converter_unit_distance_convert(MultiConverterState* const multi_converter_state) {
  109. double a = strtof(multi_converter_state->buffer_orig, NULL);
  110. uint8_t overflow = 0;
  111. switch(multi_converter_state->unit_type_orig) {
  112. default:
  113. break;
  114. case UnitTypeKilometers:
  115. if(multi_converter_state->unit_type_dest == UnitTypeMeters)
  116. a *= ((double)1000);
  117. else if(multi_converter_state->unit_type_dest == UnitTypeCentimeters)
  118. a *= ((double)100000);
  119. else if(multi_converter_state->unit_type_dest == UnitTypeMiles)
  120. a *= ((double)0.6213711);
  121. else if(multi_converter_state->unit_type_dest == UnitTypeFeet)
  122. a *= ((double)3280.839895013);
  123. else if(multi_converter_state->unit_type_dest == UnitTypeInches)
  124. a *= ((double)39370.078740157);
  125. break;
  126. case UnitTypeMeters:
  127. if(multi_converter_state->unit_type_dest == UnitTypeKilometers)
  128. a /= ((double)1000);
  129. else if(multi_converter_state->unit_type_dest == UnitTypeCentimeters)
  130. a *= ((double)100);
  131. else if(multi_converter_state->unit_type_dest == UnitTypeMiles)
  132. a *= ((double)0.0006213711);
  133. else if(multi_converter_state->unit_type_dest == UnitTypeFeet)
  134. a *= ((double)3.280839895013);
  135. else if(multi_converter_state->unit_type_dest == UnitTypeInches)
  136. a *= ((double)39.370078740157);
  137. break;
  138. case UnitTypeCentimeters:
  139. if(multi_converter_state->unit_type_dest == UnitTypeKilometers)
  140. a /= ((double)100000);
  141. else if(multi_converter_state->unit_type_dest == UnitTypeMeters)
  142. a /= ((double)100);
  143. else if(multi_converter_state->unit_type_dest == UnitTypeMiles)
  144. a *= ((double)0.000006213711);
  145. else if(multi_converter_state->unit_type_dest == UnitTypeFeet)
  146. a *= ((double)0.03280839895013);
  147. else if(multi_converter_state->unit_type_dest == UnitTypeInches)
  148. a *= ((double)0.39370078740157);
  149. break;
  150. case UnitTypeMiles:
  151. if(multi_converter_state->unit_type_dest == UnitTypeKilometers)
  152. a *= ((double)1.609344);
  153. else if(multi_converter_state->unit_type_dest == UnitTypeMeters)
  154. a *= ((double)1609.344);
  155. else if(multi_converter_state->unit_type_dest == UnitTypeCentimeters)
  156. a *= ((double)160934.4);
  157. else if(multi_converter_state->unit_type_dest == UnitTypeFeet)
  158. a *= ((double)5280);
  159. else if(multi_converter_state->unit_type_dest == UnitTypeInches)
  160. a *= ((double)63360);
  161. break;
  162. case UnitTypeFeet:
  163. if(multi_converter_state->unit_type_dest == UnitTypeKilometers)
  164. a *= ((double)0.0003048);
  165. else if(multi_converter_state->unit_type_dest == UnitTypeMeters)
  166. a *= ((double)0.3048);
  167. else if(multi_converter_state->unit_type_dest == UnitTypeCentimeters)
  168. a *= ((double)30.48);
  169. else if(multi_converter_state->unit_type_dest == UnitTypeMiles)
  170. a *= ((double)0.000189393939394);
  171. else if(multi_converter_state->unit_type_dest == UnitTypeInches)
  172. a *= ((double)12);
  173. break;
  174. case UnitTypeInches:
  175. if(multi_converter_state->unit_type_dest == UnitTypeKilometers)
  176. a *= ((double)0.0000254);
  177. else if(multi_converter_state->unit_type_dest == UnitTypeMeters)
  178. a *= ((double)0.0254);
  179. else if(multi_converter_state->unit_type_dest == UnitTypeCentimeters)
  180. a *= ((double)2.54);
  181. else if(multi_converter_state->unit_type_dest == UnitTypeMiles)
  182. a *= ((double)0.0000157828282828);
  183. else if(multi_converter_state->unit_type_dest == UnitTypeFeet)
  184. a *= ((double)0.0833333333333);
  185. break;
  186. }
  187. if(overflow) {
  188. multi_converter_unit_set_overflow(multi_converter_state->buffer_dest);
  189. } else {
  190. int ret = snprintf(
  191. multi_converter_state->buffer_dest, MULTI_CONVERTER_NUMBER_DIGITS + 1, "%lf", a);
  192. if(ret < 0) multi_converter_unit_set_overflow(multi_converter_state->buffer_dest);
  193. }
  194. }
  195. uint8_t multi_converter_unit_distance_allowed(MultiConverterUnitType unit_type) {
  196. return (
  197. unit_type == UnitTypeKilometers || unit_type == UnitTypeMeters ||
  198. unit_type == UnitTypeCentimeters || unit_type == UnitTypeMiles ||
  199. unit_type == UnitTypeFeet || unit_type == UnitTypeInches);
  200. }
  201. //
  202. // DEG / RAD
  203. //
  204. void multi_converter_unit_angle_convert(MultiConverterState* const multi_converter_state) {
  205. double a = strtof(multi_converter_state->buffer_orig, NULL);
  206. uint8_t overflow = 0;
  207. switch(multi_converter_state->unit_type_orig) {
  208. default:
  209. break;
  210. case UnitTypeDegree:
  211. if(multi_converter_state->unit_type_dest == UnitTypeRadian) a *= ((double)0.0174532925199);
  212. break;
  213. case UnitTypeRadian:
  214. if(multi_converter_state->unit_type_dest == UnitTypeDegree) a *= ((double)57.2957795131);
  215. break;
  216. }
  217. if(overflow) {
  218. multi_converter_unit_set_overflow(multi_converter_state->buffer_dest);
  219. } else {
  220. int ret = snprintf(
  221. multi_converter_state->buffer_dest, MULTI_CONVERTER_NUMBER_DIGITS + 1, "%lf", a);
  222. if(ret < 0) multi_converter_unit_set_overflow(multi_converter_state->buffer_dest);
  223. }
  224. }
  225. uint8_t multi_converter_unit_angle_allowed(MultiConverterUnitType unit_type) {
  226. return (unit_type == UnitTypeDegree || unit_type == UnitTypeRadian);
  227. }