fork(1) download
  1. /*
  2.  * 整数。
  3.  *
  4.  * Date: 2014-04-11
  5.  * Author: Leonardone
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10.  
  11. #define DEBUG_FLAG 1
  12.  
  13. #if DEBUG_FLAG
  14. # define DebugDo(d) d
  15. #else
  16. # define DebugDo(d)
  17. #endif
  18.  
  19. struct _digit;
  20. struct _decimal;
  21. typedef struct _digit Digit, *LPDigit;
  22. typedef struct _decimal Decimal, *LPDecimal;
  23.  
  24. struct _digit {
  25. int value;
  26. LPDigit upper;
  27. LPDigit under;
  28. };
  29.  
  30. struct _decimal {
  31. int point;
  32. int sign;
  33. LPDigit head;
  34. LPDigit tail;
  35. };
  36.  
  37. LPDigit newDigit(void);
  38. LPDigit newDigitByInt(int value);
  39. int countDigits(const LPDecimal dec);
  40. LPDecimal newDecimal(void);
  41. LPDecimal newDecimalByInt(int value);
  42. void printDecimal(const LPDecimal dec);
  43. LPDecimal addDecimal(LPDecimal val1, LPDecimal val2);
  44. LPDecimal mulDecimal(LPDecimal val1, LPDecimal val2);
  45. void releaseDecimal(LPDecimal dec);
  46. void releaseDigit(LPDigit dig);
  47.  
  48. int main(void) {
  49.  
  50. LPDecimal d1 = newDecimalByInt(111);
  51. LPDecimal d2 = newDecimalByInt(2222);
  52. LPDecimal d3 = newDecimalByInt(999);
  53. LPDecimal d4 = addDecimal(d1, d2);
  54. LPDecimal d5 = addDecimal(d1, d3);
  55. LPDecimal d6 = addDecimal(d2, d3);
  56.  
  57. printDecimal(d1);
  58. printDecimal(d2);
  59. printDecimal(d3);
  60. printDecimal(d4);
  61. printDecimal(d5);
  62. printDecimal(d6);
  63.  
  64. releaseDecimal(d1);
  65. releaseDecimal(d2);
  66. releaseDecimal(d3);
  67. releaseDecimal(d4);
  68. releaseDecimal(d5);
  69. releaseDecimal(d6);
  70.  
  71. return 0;
  72. }
  73.  
  74. LPDigit newDigit(void) {
  75. return (LPDigit)calloc(1, sizeof(Digit));
  76. }
  77.  
  78. LPDigit newDigitByInt(int value) {
  79. LPDigit dig = newDigit();
  80. if (value > 9) {
  81. dig->upper = newDigitByInt(value / 10);
  82. dig->upper->under = dig;
  83. }
  84. dig->value = value % 10;
  85. return dig;
  86. }
  87.  
  88. int countDigits(const LPDecimal dec) {
  89. LPDigit dig = dec->head;
  90. int i = 0;
  91. while (dig != NULL) {
  92. i++;
  93. dig = dig->under;
  94. }
  95. return i;
  96. }
  97.  
  98. LPDecimal newDecimal(void) {
  99. return newDecimalByInt(0);
  100. }
  101.  
  102. LPDecimal newDecimalByInt(int value) {
  103. LPDecimal dec = (LPDecimal)calloc(1, sizeof(Decimal));
  104. LPDigit dig;
  105. if (value < 0) {
  106. dec->sign = 1;
  107. value *= -1;
  108. }
  109. dec->tail = dig = newDigitByInt(value);
  110. while (dig->upper != NULL) {
  111. dig = dig->upper;
  112. }
  113. dec->head = dig;
  114. dec->point = countDigits(dec);
  115. return dec;
  116. }
  117.  
  118. void releaseDigit(LPDigit dig) {
  119. if (dig->under != NULL) {
  120. dig->under->upper = NULL;
  121. releaseDigit(dig->under);
  122. dig->under = NULL;
  123. }
  124. if (dig->upper != NULL) {
  125. dig->upper->under = NULL;
  126. releaseDigit(dig->upper);
  127. dig->upper = NULL;
  128. }
  129. DebugDo(printf("release Digit: %d\n", dig->value));
  130. free(dig);
  131. }
  132.  
  133. void releaseDecimal(LPDecimal dec) {
  134. DebugDo(printf("release Decimal: "));
  135. DebugDo(printDecimal(dec));
  136. releaseDigit(dec->head);
  137. dec->head = NULL;
  138. dec->tail = NULL;
  139. free(dec);
  140. }
  141.  
  142. void printDecimal(const LPDecimal dec) {
  143. int p = dec->point;
  144. LPDigit dig = dec->head;
  145. if (dec->sign) {
  146. putchar('-');
  147. }
  148. while (p > 1 && dig != NULL && dig->value == 0) {
  149. dig = dig->under;
  150. p--;
  151. }
  152. while (p > 0 && dig != NULL) {
  153. putchar('0' + (char)dig->value);
  154. dig = dig->under;
  155. p--;
  156. }
  157. if (p > 0) {
  158. printf("error\n");
  159. exit(1);
  160. }
  161. if (dig != NULL) {
  162. putchar('.');
  163. while (dig != NULL) {
  164. putchar('0' + (char)dig->value);
  165. dig = dig->under;
  166. }
  167. }
  168. putchar('\n');
  169. }
  170.  
  171. LPDecimal addDecimal(LPDecimal val1, LPDecimal val2) {
  172. LPDecimal val3 = newDecimal();
  173. LPDigit dig1 = val1->tail;
  174. LPDigit dig2 = val2->tail;
  175. LPDigit dig3 = val3->tail;
  176. int p1 = val1->point;
  177. int p2 = val2->point;
  178. int c1 = countDigits(val1) - p1;
  179. int c2 = countDigits(val2) - p2;
  180. int c3 = c1 > c2 ? c1 : c2;
  181. int t1, t2, t3, ca;
  182.  
  183. if (val1->sign != val2->sign) {
  184. return val3; /* difDecimal() */
  185. }
  186. val3->sign = val1->sign;
  187.  
  188. while (c1 < c2) {
  189. dig3->value = dig2->value;
  190. dig3->upper = newDigit();
  191. dig3->upper->under = dig3;
  192. dig2 = dig2->upper;
  193. dig3 = dig3->upper;
  194. c2--;
  195. }
  196. while (c1 > c2) {
  197. dig3->value = dig1->value;
  198. dig3->upper = newDigit();
  199. dig3->upper->under = dig3;
  200. dig1 = dig1->upper;
  201. dig3 = dig3->upper;
  202. }
  203. ca = 0;
  204. while (dig1 != NULL || dig2 != NULL) {
  205. if (dig1 != NULL) {
  206. t1 = dig1->value;
  207. dig1 = dig1->upper;
  208. } else {
  209. t1 = 0;
  210. }
  211. if (dig2 != NULL) {
  212. t2 = dig2->value;
  213. dig2 = dig2->upper;
  214. } else {
  215. t2 = 0;
  216. }
  217. t3 = t1 + t2 + ca;
  218. ca = t3 / 10;
  219. dig3->value = t3 % 10;
  220. dig3->upper = newDigit();
  221. dig3->upper->under = dig3;
  222. dig3 = dig3->upper;
  223. }
  224. if (ca > 0) {
  225. dig3->value = ca;
  226. val3->head = dig3;
  227. } else {
  228. val3->head = dig3->under;
  229. val3->head->upper = NULL;
  230. dig3->under = NULL;
  231. releaseDigit(dig3);
  232. }
  233. val3->point = countDigits(val3) - c3;
  234.  
  235. return val3;
  236. }
  237.  
  238. LPDecimal mulDecimal(LPDecimal val1, LPDecimal val2) {
  239. return NULL;
  240. }
Success #stdin #stdout 0s 2424KB
stdin
Standard input is empty
stdout
release Digit: 0
release Digit: 0
111
2222
999
2333
1110
3221
release Decimal: 111
release Digit: 1
release Digit: 1
release Digit: 1
release Decimal: 2222
release Digit: 2
release Digit: 2
release Digit: 2
release Digit: 2
release Decimal: 999
release Digit: 9
release Digit: 9
release Digit: 9
release Decimal: 2333
release Digit: 3
release Digit: 3
release Digit: 3
release Digit: 2
release Decimal: 1110
release Digit: 0
release Digit: 1
release Digit: 1
release Digit: 1
release Decimal: 3221
release Digit: 1
release Digit: 2
release Digit: 2
release Digit: 3