Advertisement
Guest User

Untitled

a guest
Nov 27th, 2015
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.18 KB | None | 0 0
  1. #include "expr.h"
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <ctype.h>
  5. #include <stdio.h>
  6.  
  7. #define ISPMO(x) (((x) == '+') || ((x) == '-'))
  8. #define ISMDO(x) (((x) == '*') || ((x) == '/'))
  9. #define ISO(x) (ISPMO(x) || ISMDO (x))
  10. #define ISDIG(x) (isdigit(x) || ((x) == '.'))
  11.  
  12. extern int global_scale;
  13.  
  14. char *substr(const char *source, int start, int end)
  15. {
  16. char *res = malloc(sizeof(char) * (end - start + 1));
  17. for (int i = 0; i < end - start; ++i) {
  18. res[i] = source[i + start];
  19. }
  20. res[end - start] = '\0';
  21. return res;
  22. }
  23.  
  24. void pre_process(char *source)
  25. {
  26. for (int i = 0; i < strlen(source); ++i) {
  27. if (source[i] == ' ' || source[i] == '\t') {
  28. for (int j = i; j < strlen(source); ++j) {
  29. source[j] = source[j + 1];
  30. }
  31. --i;
  32. }
  33. }
  34. }
  35.  
  36. expr_node *parse_expr(const char *source)
  37. {
  38. expr_node *head;
  39. int brackets = 0;
  40. int allnums = 1;
  41. int occur1 = -1, occur2 = -1;
  42. int out_of_bracket_once = 0;
  43. for (int i = (int)strlen(source) - 1; i >= 0; --i) {
  44. if (!ISDIG(source[i])) {
  45. if (i != 0 || (i == 0 && !ISPMO(source[i]))) {
  46. allnums = 0;
  47. }
  48. if (ISPMO(source[i]) && !brackets) {
  49. if (i != 0 && ISO(source[i - 1])) {
  50. continue;
  51. } else {
  52. occur1 = i;
  53. break;
  54. }
  55. } else if (ISMDO(source[i]) && !brackets && occur2 == -1) {
  56. occur2 = i;
  57. } else if (source[i] == ')') {
  58. ++brackets;
  59. } else if (source[i] == '(') {
  60. --brackets;
  61. }
  62. }
  63. if ((i < (int)strlen(source) - 1) && (i > 0) && !brackets) {
  64. out_of_bracket_once = 1;
  65. }
  66. }
  67.  
  68. if (!out_of_bracket_once && occur1 == -1 && !allnums) {
  69. char *middle = substr(source, 1, (int)strlen(source) - 1);
  70. head = parse_expr(middle);
  71. free(middle);
  72. return head;
  73. }
  74.  
  75. char *left;
  76. char *right;
  77. if (allnums) {
  78. head = malloc(sizeof(expr_node));
  79. head -> type = EXPR_NUMBER;
  80. head -> left_child = NULL;
  81. head -> right_child = NULL;
  82. head -> value = atoreal((const char*)source);
  83. } else if (occur1 > 0) {
  84. head = malloc(sizeof(expr_node));
  85. head -> type = source[occur1] == '+' ? EXPR_PLUS : EXPR_MINUS;
  86. left = substr(source, 0, occur1);
  87. right = substr(source, occur1 + 1, (int)strlen(source));
  88. head -> left_child = parse_expr((const char*)left);
  89. head -> right_child = parse_expr((const char*)right);
  90. free(left);
  91. free(right);
  92. } else if (occur2 > 0) {
  93. head = malloc(sizeof(expr_node));
  94. head -> type = source[occur2] == '*' ? EXPR_MUL : EXPR_DIV;
  95. left = substr(source, 0, occur2);
  96. right = substr(source, occur2 + 1, (int)strlen(source));
  97. head -> left_child = parse_expr((const char*)left);
  98. head -> right_child = parse_expr((const char*)right);
  99. free(left);
  100. free(right);
  101. }
  102.  
  103. return head;
  104. }
  105.  
  106. lrealn cal_expr(expr_node *source)
  107. {
  108. switch (source -> type) {
  109. case EXPR_NUMBER:
  110. return source -> value;
  111. case EXPR_PLUS:
  112. return add_real(cal_expr(source -> left_child), cal_expr(source -> right_child));
  113. case EXPR_MINUS:
  114. return minus_real(cal_expr(source -> left_child), cal_expr(source -> right_child));
  115. case EXPR_MUL:
  116. return multi_real(cal_expr(source -> left_child), cal_expr(source -> right_child));
  117. case EXPR_DIV:
  118. return div_real(cal_expr(source -> left_child), cal_expr(source -> right_child));
  119. default:
  120. return zeroreal();
  121. break;
  122. }
  123. }
  124.  
  125. void delete_expr_tree(expr_node *item)
  126. {
  127. if (item == NULL) {
  128. return;
  129. } else if (item -> type == EXPR_NUMBER) {
  130. free(item);
  131. } else {
  132. delete_expr_tree(item -> left_child);
  133. delete_expr_tree(item -> right_child);
  134. free(item);
  135. }
  136. }
  137.  
  138. lrealn add_real(lrealn v1, lrealn v2)
  139. {
  140. lrealn res;
  141. if (v1.scale == v2.scale) {
  142. res.scale = v1.scale;
  143. res.value = v1.value + v2.value;
  144. } else if (v1.scale > v2.scale) {
  145. while (v1.scale > v2.scale) {
  146. ++v2.scale;
  147. v2.value *= 10;
  148. }
  149. res.scale = v1.scale;
  150. res.value = v1.value + v2.value;
  151. } else {
  152. while (v1.scale < v2.scale) {
  153. ++v1.scale;
  154. v1.value *= 10;
  155. }
  156. res.scale = v1.scale;
  157. res.value = v1.value + v2.value;
  158. }
  159.  
  160. while (res.value % 10 == 0 && res.value != 0) {
  161. res.value /= 10;
  162. --res.scale;
  163. }
  164.  
  165. return res;
  166. }
  167.  
  168. lrealn minus_real(lrealn v1, lrealn v2)
  169. {
  170. v2.value = -v2.value;
  171. return add_real(v1, v2);
  172. }
  173.  
  174. lrealn multi_real(lrealn v1, lrealn v2)
  175. {
  176. lrealn res;
  177. res.value = v1.value * v2.value;
  178. res.scale = v1.scale + v2.scale;
  179.  
  180. while (res.value % 10 == 0 && res.value != 0) {
  181. res.value /= 10;
  182. --res.scale;
  183. }
  184.  
  185. return res;
  186. }
  187.  
  188. lrealn div_real(lrealn v1, lrealn v2)
  189. {
  190. lrealn res;
  191. if (v1.scale == v2.scale) {
  192. res.scale = v1.scale;
  193. res.value = v1.value / v2.value;
  194. } else if (v1.scale > v2.scale) {
  195. while (v1.scale > v2.scale) {
  196. ++v2.scale;
  197. v2.value *= 10;
  198. }
  199. } else {
  200. while (v1.scale < v2.scale) {
  201. ++v1.scale;
  202. v1.value *= 10;
  203. }
  204. }
  205.  
  206. while (v1.scale < global_scale + v2.scale) {
  207. v1.value *= 10;
  208. ++v1.scale;
  209. }
  210. res.scale = global_scale;
  211. res.value = v1.value / v2.value;
  212.  
  213. while (res.value % 10 == 0 && res.value != 0) {
  214. res.value /= 10;
  215. --res.scale;
  216. }
  217.  
  218. return res;
  219. }
  220.  
  221. lrealn createreal(long long val, int sca)
  222. {
  223. lrealn res;
  224. res.value = val;
  225. res.scale = sca;
  226. return res;
  227. }
  228.  
  229. lrealn atoreal(const char *source)
  230. {
  231. lrealn res;
  232. res.value = 0;
  233. res.scale = 0;
  234. int exponent = 1;
  235. for (int i = (int)strlen(source) - 1; i >= 0; --i) {
  236. if (isdigit(source[i])) {
  237. res.value += ((source[i] - '0') * exponent);
  238. exponent *= 10;
  239. } else if (source[i] == '.') {
  240. res.scale = (int)strlen(source) - i - 1;
  241. }
  242. }
  243. if (source[0] == '-') {
  244. res.value *= -1;
  245. }
  246. return res;
  247. }
  248.  
  249. lrealn zeroreal()
  250. {
  251. lrealn res;
  252. res.value = 0;
  253. res.scale = 0;
  254. return res;
  255. }
  256.  
  257. void print_real(lrealn source)
  258. {
  259. long long intpart = source.value;
  260. long long times = 1;
  261. int length = vallen(source.value);
  262. for (int i = 0; i < source.scale; ++i) {
  263. intpart /= 10;
  264. times *= 10;
  265. }
  266. if (length > source.scale) {
  267. if (source.scale > 0 && source.value != 0) {
  268. printf("%lld.%lld\n", intpart, source.value - intpart * times);
  269. } else {
  270. printf("%lld\n", source.value);
  271. }
  272. } else {
  273. printf("0.");
  274. for (int i = 0; i < source.scale - length; ++i) {
  275. putchar('0');
  276. }
  277. printf("%lld\n", source.value);
  278. }
  279. }
  280.  
  281. int vallen(long long source)
  282. {
  283. int length = 0;
  284. while (source != 0) {
  285. source /= 10;
  286. ++length;
  287. }
  288. return length;
  289. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement