It's a stack calculator for the unwise. Public Domain.
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
Tento repozitář je archivovaný. Můžete prohlížet soubory, klonovat, ale nemůžete nahrávat a vytvářet nové úkoly a požadavky na natažení.

105 řádky
3.9KB

  1. #define ARITH(fn, op) \
  2. static inline int \
  3. fn(ns_t * s) \
  4. { \
  5. if (s->top > 0) \
  6. { \
  7. --s->top; \
  8. op(NS_PEEK(s), \
  9. NS_PEEK(s), s->num[s->top+1]); \
  10. return 0; \
  11. } \
  12. else \
  13. { \
  14. fprintf(stderr, "dc: underflow\n"); \
  15. return 1; \
  16. } \
  17. }
  18. #define ARITH_ONE(fn, op) \
  19. static inline int \
  20. fn(ns_t * s) \
  21. { \
  22. if (s->top > -1) \
  23. { \
  24. op(NS_PEEK(s), \
  25. NS_PEEK(s)); \
  26. return 0; \
  27. } \
  28. else \
  29. { \
  30. fprintf(stderr, "dc: underflow\n"); \
  31. return 1; \
  32. } \
  33. }
  34. #define ARITH_DIV(fn, op) \
  35. static inline int fn(ns_t * s) \
  36. { \
  37. if (s->top > 0) \
  38. { \
  39. if (!(mpf_cmp_ui(NS_PEEK(s), 0) || \
  40. mpf_cmp_ui(s->num[s->top-1], 0))) \
  41. { fprintf(stderr, "dc: divide by 0\n"); return 2; } \
  42. else \
  43. { \
  44. --s->top; op(NS_PEEK(s), NS_PEEK(s), s->num[s->top+1]); \
  45. return 0; \
  46. } \
  47. } \
  48. else \
  49. { fprintf(stderr, "dc: underflow\n"); return 1; } \
  50. }
  51. /* handles negative numbers and is multi-presision unlike mpf_exp_ui */
  52. static inline int ns_exp(ns_t * s)
  53. {
  54. if (s->top > 0)
  55. {
  56. if (!(mpf_cmp_ui(NS_PEEK(s), 0) ||
  57. mpf_cmp_ui(s->num[s->top-1], 0)))
  58. { fprintf(stderr, "dc: divide by 0\n"); return 2; }
  59. else
  60. {
  61. mpf_t i;
  62. mpf_t mpf;
  63. if (mpf_cmp_ui(NS_PEEK(s), 0) == 0)
  64. { mpf_set_ui(NS_PEEK(s), 1); return 0; }
  65. --s->top;
  66. mpf_inits(i, mpf, NULL);
  67. mpf_set(mpf, NS_PEEK(s));
  68. mpf_set(i, s->num[s->top + 1]);
  69. mpf_ceil(i, i);
  70. mpf_sub_ui(i, i, 1);
  71. if (mpf_cmp_ui(i, 0) > 0)
  72. {
  73. for (; mpf_cmp_ui(i, 0); mpf_sub_ui(i, i, 1))
  74. { mpf_mul(NS_PEEK(s), NS_PEEK(s), mpf); }
  75. }
  76. else
  77. {
  78. for (; mpf_cmp_ui(i, 0); mpf_add_ui(i, i, 1))
  79. { mpf_div(NS_PEEK(s), NS_PEEK(s), mpf); }
  80. }
  81. mpf_clears(i, mpf, NULL);
  82. return 0;
  83. }
  84. {
  85. }
  86. }
  87. else
  88. { fprintf(stderr, "dc: underflow\n"); return 1; }
  89. __builtin_unreachable();
  90. }
  91. ARITH(ns_add, mpf_add)
  92. ARITH(ns_sub, mpf_sub)
  93. ARITH(ns_mul, mpf_mul)
  94. ARITH_DIV(ns_div, mpf_div)
  95. ARITH_DIV(ns_mod, mpf_div)
  96. ARITH_ONE(ns_abs, mpf_abs)
  97. ARITH_ONE(ns_sqrt, mpf_sqrt)
  98. ARITH_ONE(ns_floor, mpf_floor)
  99. ARITH_ONE(ns_ceil, mpf_ceil)