_decimal_build.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. import os
  2. import sys
  3. from cffi import FFI
  4. ffi = FFI()
  5. ffi.cdef("""
  6. typedef size_t mpd_size_t; /* unsigned size type */
  7. typedef ssize_t mpd_ssize_t; /* signed size type */
  8. typedef size_t mpd_uint_t;
  9. #define MPD_SIZE_MAX ...
  10. #define MPD_SSIZE_MIN ...
  11. #define MPD_SSIZE_MAX ...
  12. const char *mpd_version(void);
  13. void mpd_free(void *ptr);
  14. typedef struct mpd_context_t {
  15. mpd_ssize_t prec; /* precision */
  16. mpd_ssize_t emax; /* max positive exp */
  17. mpd_ssize_t emin; /* min negative exp */
  18. uint32_t traps; /* status events that should be trapped */
  19. uint32_t status; /* status flags */
  20. uint32_t newtrap; /* set by mpd_addstatus_raise() */
  21. int round; /* rounding mode */
  22. int clamp; /* clamp mode */
  23. int allcr; /* all functions correctly rounded */
  24. } mpd_context_t;
  25. enum {
  26. MPD_ROUND_UP, /* round away from 0 */
  27. MPD_ROUND_DOWN, /* round toward 0 (truncate) */
  28. MPD_ROUND_CEILING, /* round toward +infinity */
  29. MPD_ROUND_FLOOR, /* round toward -infinity */
  30. MPD_ROUND_HALF_UP, /* 0.5 is rounded up */
  31. MPD_ROUND_HALF_DOWN, /* 0.5 is rounded down */
  32. MPD_ROUND_HALF_EVEN, /* 0.5 is rounded to even */
  33. MPD_ROUND_05UP, /* round zero or five away from 0 */
  34. MPD_ROUND_TRUNC, /* truncate, but set infinity */
  35. MPD_ROUND_GUARD
  36. };
  37. #define MPD_Clamped ...
  38. #define MPD_Conversion_syntax ...
  39. #define MPD_Division_by_zero ...
  40. #define MPD_Division_impossible ...
  41. #define MPD_Division_undefined ...
  42. #define MPD_Float_operation ...
  43. #define MPD_Fpu_error ...
  44. #define MPD_Inexact ...
  45. #define MPD_Invalid_context ...
  46. #define MPD_Invalid_operation ...
  47. #define MPD_Malloc_error ...
  48. #define MPD_Not_implemented ...
  49. #define MPD_Overflow ...
  50. #define MPD_Rounded ...
  51. #define MPD_Subnormal ...
  52. #define MPD_Underflow ...
  53. #define MPD_Max_status ...
  54. /* Conditions that result in an IEEE 754 exception */
  55. #define MPD_IEEE_Invalid_operation ...
  56. /* Errors that require the result of an operation to be set to NaN */
  57. #define MPD_Errors ...
  58. void mpd_maxcontext(mpd_context_t *ctx);
  59. int mpd_qsetprec(mpd_context_t *ctx, mpd_ssize_t prec);
  60. int mpd_qsetemax(mpd_context_t *ctx, mpd_ssize_t emax);
  61. int mpd_qsetemin(mpd_context_t *ctx, mpd_ssize_t emin);
  62. int mpd_qsetround(mpd_context_t *ctx, int newround);
  63. int mpd_qsettraps(mpd_context_t *ctx, uint32_t flags);
  64. int mpd_qsetstatus(mpd_context_t *ctx, uint32_t flags);
  65. int mpd_qsetclamp(mpd_context_t *ctx, int c);
  66. typedef struct mpd_t {
  67. uint8_t flags;
  68. mpd_ssize_t exp;
  69. mpd_ssize_t digits;
  70. mpd_ssize_t len;
  71. mpd_ssize_t alloc;
  72. mpd_uint_t *data;
  73. } mpd_t;
  74. #define MPD_POS ...
  75. #define MPD_NEG ...
  76. #define MPD_INF ...
  77. #define MPD_NAN ...
  78. #define MPD_SNAN ...
  79. #define MPD_SPECIAL ...
  80. #define MPD_STATIC ...
  81. #define MPD_STATIC_DATA ...
  82. #define MPD_SHARED_DATA ...
  83. #define MPD_CONST_DATA ...
  84. #define MPD_DATAFLAGS ...
  85. mpd_t *mpd_qnew(void);
  86. void mpd_del(mpd_t *dec);
  87. /* Operations */
  88. void mpd_qabs(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
  89. void mpd_qplus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
  90. void mpd_qminus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
  91. void mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
  92. void mpd_qexp(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
  93. void mpd_qln(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
  94. void mpd_qlog10(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
  95. void mpd_qlogb(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
  96. void mpd_qinvert(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
  97. void mpd_qmax(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
  98. void mpd_qmax_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
  99. void mpd_qmin(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
  100. void mpd_qmin_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
  101. void mpd_qadd(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
  102. void mpd_qsub(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
  103. void mpd_qmul(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
  104. void mpd_qdiv(mpd_t *q, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
  105. void mpd_qdivint(mpd_t *q, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
  106. void mpd_qfma(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_t *c, const mpd_context_t *ctx, uint32_t *status);
  107. void mpd_qrem(mpd_t *r, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
  108. void mpd_qrem_near(mpd_t *r, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
  109. void mpd_qpow(mpd_t *result, const mpd_t *base, const mpd_t *exp, const mpd_context_t *ctx, uint32_t *status);
  110. void mpd_qpowmod(mpd_t *result, const mpd_t *base, const mpd_t *exp, const mpd_t *mod, const mpd_context_t *ctx, uint32_t *status);
  111. int mpd_qcopy_sign(mpd_t *result, const mpd_t *a, const mpd_t *b, uint32_t *status);
  112. int mpd_qcopy_abs(mpd_t *result, const mpd_t *a, uint32_t *status);
  113. int mpd_qcopy_negate(mpd_t *result, const mpd_t *a, uint32_t *status);
  114. void mpd_qdivmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
  115. void mpd_qand(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
  116. void mpd_qor(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
  117. void mpd_qxor(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
  118. int mpd_same_quantum(const mpd_t *a, const mpd_t *b);
  119. void mpd_qround_to_intx(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
  120. void mpd_qround_to_int(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
  121. int mpd_qcopy(mpd_t *result, const mpd_t *a, uint32_t *status);
  122. int mpd_qcmp(const mpd_t *a, const mpd_t *b, uint32_t *status);
  123. int mpd_qcompare(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
  124. int mpd_qcompare_signal(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
  125. int mpd_compare_total(mpd_t *result, const mpd_t *a, const mpd_t *b);
  126. int mpd_compare_total_mag(mpd_t *result, const mpd_t *a, const mpd_t *b);
  127. void mpd_qnext_toward(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
  128. void mpd_qnext_minus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
  129. void mpd_qnext_plus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
  130. void mpd_qquantize(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
  131. void mpd_qrotate(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
  132. void mpd_qscaleb(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
  133. void mpd_qshift(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
  134. void mpd_qreduce(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
  135. /* Get attributes */
  136. uint8_t mpd_sign(const mpd_t *dec);
  137. int mpd_isnegative(const mpd_t *dec);
  138. int mpd_ispositive(const mpd_t *dec);
  139. int mpd_iszero(const mpd_t *dec);
  140. int mpd_isfinite(const mpd_t *dec);
  141. int mpd_isinfinite(const mpd_t *dec);
  142. int mpd_issigned(const mpd_t *dec);
  143. int mpd_isnan(const mpd_t *dec);
  144. int mpd_issnan(const mpd_t *dec);
  145. int mpd_isspecial(const mpd_t *dec);
  146. int mpd_isqnan(const mpd_t *dec);
  147. int mpd_isnormal(const mpd_t *dec, const mpd_context_t *ctx);
  148. int mpd_issubnormal(const mpd_t *dec, const mpd_context_t *ctx);
  149. mpd_ssize_t mpd_adjexp(const mpd_t *dec);
  150. mpd_ssize_t mpd_etiny(const mpd_context_t *ctx);
  151. mpd_ssize_t mpd_etop(const mpd_context_t *ctx);
  152. mpd_t *mpd_qncopy(const mpd_t *a);
  153. /* Set attributes */
  154. void mpd_set_sign(mpd_t *result, uint8_t sign);
  155. void mpd_set_positive(mpd_t *result);
  156. void mpd_clear_flags(mpd_t *result);
  157. void mpd_seterror(mpd_t *result, uint32_t flags, uint32_t *status);
  158. void mpd_setspecial(mpd_t *dec, uint8_t sign, uint8_t type);
  159. /* I/O */
  160. void mpd_qimport_u16(mpd_t *result, const uint16_t *srcdata, size_t srclen,
  161. uint8_t srcsign, uint32_t srcbase,
  162. const mpd_context_t *ctx, uint32_t *status);
  163. size_t mpd_qexport_u16(uint16_t **rdata, size_t rlen, uint32_t base,
  164. const mpd_t *src, uint32_t *status);
  165. void mpd_qset_string(mpd_t *dec, const char *s, const mpd_context_t *ctx, uint32_t *status);
  166. void mpd_qset_uint(mpd_t *result, mpd_uint_t a, const mpd_context_t *ctx, uint32_t *status);
  167. void mpd_qset_ssize(mpd_t *result, mpd_ssize_t a, const mpd_context_t *ctx, uint32_t *status);
  168. void mpd_qsset_ssize(mpd_t *result, mpd_ssize_t a, const mpd_context_t *ctx, uint32_t *status);
  169. mpd_ssize_t mpd_qget_ssize(const mpd_t *dec, uint32_t *status);
  170. int mpd_lsnprint_signals(char *dest, int nmemb, uint32_t flags, const char *signal_string[]);
  171. #define MPD_MAX_SIGNAL_LIST ...
  172. const char *dec_signal_string[];
  173. void mpd_qfinalize(mpd_t *result, const mpd_context_t *ctx, uint32_t *status);
  174. const char *mpd_class(const mpd_t *a, const mpd_context_t *ctx);
  175. /* format specification */
  176. typedef struct mpd_spec_t {
  177. mpd_ssize_t min_width; /* minimum field width */
  178. mpd_ssize_t prec; /* fraction digits or significant digits */
  179. char type; /* conversion specifier */
  180. char align; /* alignment */
  181. char sign; /* sign printing/alignment */
  182. char fill[5]; /* fill character */
  183. const char *dot; /* decimal point */
  184. const char *sep; /* thousands separator */
  185. const char *grouping; /* grouping of digits */
  186. } mpd_spec_t;
  187. char *mpd_to_sci(const mpd_t *dec, int fmt);
  188. char *mpd_to_eng(const mpd_t *dec, int fmt);
  189. int mpd_parse_fmt_str(mpd_spec_t *spec, const char *fmt, int caps);
  190. int mpd_validate_lconv(mpd_spec_t *spec);
  191. char *mpd_qformat_spec(const mpd_t *dec, const mpd_spec_t *spec, const mpd_context_t *ctx, uint32_t *status);
  192. """)
  193. _libdir = os.path.join(os.path.dirname(__file__), '_libmpdec')
  194. ffi.set_source('_decimal_cffi',
  195. """
  196. #ifdef _MSC_VER
  197. #if defined(_WIN64)
  198. typedef __int64 LONG_PTR;
  199. #else
  200. typedef long LONG_PTR;
  201. #endif
  202. typedef LONG_PTR ssize_t;
  203. #else
  204. #define HAVE_STDINT_H
  205. #endif
  206. #include "mpdecimal.h"
  207. #define MPD_Float_operation MPD_Not_implemented
  208. const char *dec_signal_string[MPD_NUM_FLAGS] = {
  209. "Clamped",
  210. "InvalidOperation",
  211. "DivisionByZero",
  212. "InvalidOperation",
  213. "InvalidOperation",
  214. "InvalidOperation",
  215. "Inexact",
  216. "InvalidOperation",
  217. "InvalidOperation",
  218. "InvalidOperation",
  219. "FloatOperation",
  220. "Overflow",
  221. "Rounded",
  222. "Subnormal",
  223. "Underflow",
  224. };
  225. """,
  226. sources=[os.path.join(_libdir, 'mpdecimal.c'),
  227. os.path.join(_libdir, 'basearith.c'),
  228. os.path.join(_libdir, 'convolute.c'),
  229. os.path.join(_libdir, 'constants.c'),
  230. os.path.join(_libdir, 'context.c'),
  231. os.path.join(_libdir, 'io.c'),
  232. os.path.join(_libdir, 'fourstep.c'),
  233. os.path.join(_libdir, 'sixstep.c'),
  234. os.path.join(_libdir, 'transpose.c'),
  235. os.path.join(_libdir, 'difradix2.c'),
  236. os.path.join(_libdir, 'numbertheory.c'),
  237. os.path.join(_libdir, 'fnt.c'),
  238. os.path.join(_libdir, 'crt.c'),
  239. os.path.join(_libdir, 'memory.c'),
  240. ],
  241. include_dirs=[_libdir],
  242. extra_compile_args=[
  243. "-DANSI",
  244. "-DHAVE_INTTYPES_H",
  245. "-DCONFIG_64" if sys.maxsize > 1 << 32 else "-DCONFIG_32",
  246. ],
  247. )
  248. if __name__ == '__main__':
  249. ffi.compile()