Advertisement
Guest User

Untitled

a guest
Mar 20th, 2019
51
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.82 KB | None | 0 0
  1. #include <assert.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <errno.h>
  6. #include <limits.h>
  7.  
  8. #define MAX_BASE() strlen(alphabet)
  9. static char const *alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  10.  
  11. static unsigned int ullong2str(char [], unsigned long long, unsigned int);
  12. static unsigned long long str2ullong(char const [], unsigned int);
  13. static char *convertToNewBase(char const [], unsigned int, unsigned int);
  14. static long indexOf(char const [], char);
  15. static unsigned long long power(unsigned int, unsigned int);
  16. static void reverse(char []);
  17.  
  18. int main(void)
  19. {
  20. char *decimal = "28697";
  21. char *binary = convertToNewBase(decimal, 10, 2);
  22.  
  23. printf("%s (base 10) = %s (base 2)n", decimal, binary);
  24. perror(NULL);
  25.  
  26. free(binary);
  27. }
  28.  
  29. /*
  30. ===============
  31. char *convertToNewBase(char [], unsigned int, unsigned int);
  32.  
  33. The function converts an unsigned integer number from the source base to
  34. destination base. The function allocates a buffer of length large enough
  35. to store the result and returns it. If an error occurs the function
  36. returns NULL.
  37. ===============
  38. */
  39. char *convertToNewBase(char const s[], unsigned int src, unsigned int dest)
  40. {
  41. assert(s);
  42. assert(src >= 2 && src <= MAX_BASE());
  43. assert(dest >= 2 && dest <= MAX_BASE());
  44.  
  45. errno = 0;
  46.  
  47. unsigned long long const n = str2ullong(s, src);
  48.  
  49. if (errno != 0)
  50. return NULL;
  51.  
  52. unsigned int const resultLength = ullong2str(NULL, n, dest);
  53. char *result = calloc(resultLength + 1, 1);
  54. if (result == NULL)
  55. return NULL;
  56.  
  57. ullong2str(result, n, dest);
  58.  
  59. return result;
  60. }
  61.  
  62. /*
  63. ===============
  64. unsigned long long ullong2str(char [], unsigned long long, unsigned int);
  65.  
  66. The function converts an unsigned integer value to a null-terminated string
  67. using the specified base and stores the result in the array given by the first
  68. parameter. It assumes that size of the array is large enough to store the
  69. result.
  70.  
  71. The function returns length of the result string. If the first parameter is
  72. NULL nothing is written, however the return value is still calculated and
  73. returned.
  74. ===============
  75. */
  76. unsigned int ullong2str(char out[], unsigned long long n, unsigned int base)
  77. {
  78. assert(base >= 2 && base <= MAX_BASE());
  79.  
  80. unsigned int i = 0;
  81.  
  82. do {
  83. if (out != NULL)
  84. out[i] = alphabet[n % base];
  85.  
  86. n /= base;
  87. i++;
  88. } while (n);
  89.  
  90. if (out != NULL) {
  91. out[i] = '';
  92. reverse(out);
  93. }
  94.  
  95. return i;
  96. }
  97.  
  98. /*
  99. ===============
  100. unsigned long long str2ullong(char const [], base_t base);
  101.  
  102. If no errors occurs the function returns an unsigned integer value
  103. corresponding to the contents of the input string. If the result is
  104. too large the function returns 0 and sets errno to ERANGE [1]. If the
  105. arguments is invalid the function return 0 and sets errno to EINVAL [2].
  106.  
  107. 1. str2llong("18446744073709551616", 10) in most cases returns 0 and sets
  108. errno to ERANGE, since 18446744073709551616 is greater than ULLONG_MAX
  109. (in most cases).
  110.  
  111. 2. str2llong("10191", 2) returns 0 and sets errno to EINVAL, since '9' is
  112. not allowed in a binary number.
  113. ===============
  114. */
  115. unsigned long long str2ullong(char const s[], unsigned int base)
  116. {
  117. assert(s != NULL);
  118. assert(base >= 2 && base <= MAX_BASE());
  119.  
  120. unsigned long long r = 0;
  121.  
  122. for (unsigned int i = strlen(s), j = 0; i-- > 0; j++) {
  123. long const index = indexOf(alphabet, s[i]);
  124. if (index == -1 || index >= (int) base) {
  125. errno = EINVAL;
  126. return 0;
  127. }
  128.  
  129. unsigned long long const t = (unsigned long long) index * power(base, j);
  130. if (r > ULLONG_MAX - t) {
  131. errno = ERANGE;
  132. return 0;
  133. }
  134.  
  135. r += t;
  136. }
  137.  
  138. return r;
  139. }
  140.  
  141. /*
  142. ===============
  143. unsigned long long power(unsigned int, unsigned int);
  144.  
  145. If no errors occurs the function returns aⁿ. If the result is too large the
  146. function returns 0 and sets errno to ERANGE.
  147. ===============
  148. */
  149. unsigned long long power(unsigned int a, unsigned int n)
  150. {
  151. unsigned long long r = 1;
  152.  
  153. while (n--) {
  154. /* If a * r would overflow… */
  155. if (a > ULLONG_MAX / r) {
  156. errno = ERANGE;
  157. return 0;
  158. }
  159.  
  160. r *= a;
  161. }
  162.  
  163. return r;
  164. }
  165.  
  166. /*
  167. ===============
  168. long indexOf(char const [], char);
  169.  
  170. The function return index of the first occurence of the character in the
  171. string. If the character is not found returns -1.
  172. ===============
  173. */
  174. long indexOf(char const s[], char c)
  175. {
  176. assert(s);
  177.  
  178. for (size_t i = 0; s[i]; i++)
  179. if (s[i] == c)
  180. return (long) i;
  181.  
  182. return -1;
  183. }
  184.  
  185. /*
  186. ===============
  187. void reverse(char []);
  188.  
  189. The function reverses the input string.
  190. ===============
  191. */
  192. void reverse(char s[])
  193. {
  194. assert(s);
  195. assert(strlen(s));
  196.  
  197. for (unsigned int i = 0, j = strlen(s) - 1; i < j; i++, j--) {
  198. char const tmp = s[i];
  199. s[i] = s[j];
  200. s[j] = tmp;
  201. }
  202. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement