1 | /******************************************************************* |
---|
2 | * IMPLEMENTATION FILE: MP_GmpBigNum.c |
---|
3 | * |
---|
4 | * The default BigInt and BigReal package is the Gnu Multiple |
---|
5 | * Precision package (see root directory for MP for licensing |
---|
6 | * details). Here we have the routines to put/get/print a GMP |
---|
7 | * bigint. |
---|
8 | * |
---|
9 | * Change Log: |
---|
10 | * 4/19/96 sgray Life begins for this file. |
---|
11 | * 5/6/96 sgray Upgraded from GMP 1.3.2 to 2.0 and added support |
---|
12 | * for GMP big reals. |
---|
13 | * 5/7/96 sgray Okay, had to fix a few bugs that crept into the |
---|
14 | * code during the night. I hate it when that happens. |
---|
15 | * 2/97 obachman Updated stuff to reflect the somewhat changed |
---|
16 | * BigNum philosphy of MP-1.1.2 and used Vector routines |
---|
17 | ************************************************************************/ |
---|
18 | |
---|
19 | #include "MP.h" |
---|
20 | |
---|
21 | #ifdef MP_HAVE_GMP_APINT |
---|
22 | |
---|
23 | MP_BigIntOps_t imp_gmp_bigint_ops = { |
---|
24 | IMP_PutGmpInt, |
---|
25 | IMP_GetGmpInt, |
---|
26 | IMP_GmpIntToStr, |
---|
27 | IMP_GmpIntAsciiSize |
---|
28 | }; |
---|
29 | |
---|
30 | #if MP_DEFAULT_APINT_FORMAT == MP_GMP |
---|
31 | MP_BigIntOps_t imp_default_bigint_ops = |
---|
32 | { |
---|
33 | IMP_PutGmpInt, |
---|
34 | IMP_GetGmpInt, |
---|
35 | IMP_GmpIntToStr, |
---|
36 | IMP_GmpIntAsciiSize |
---|
37 | }; |
---|
38 | MP_BigNumFormat_t imp_default_bigint_format = MP_GMP; |
---|
39 | #endif |
---|
40 | |
---|
41 | |
---|
42 | #ifdef __STDC__ |
---|
43 | MP_Status_t IMP_PutGmpInt(MP_Link_pt link, MP_ApInt_t mp_apint) |
---|
44 | #else |
---|
45 | MP_Status_t IMP_PutGmpInt(link, mp_apint) |
---|
46 | MP_Link_pt link; |
---|
47 | MP_ApInt_t mp_apint; |
---|
48 | #endif |
---|
49 | { |
---|
50 | mpz_ptr apint = (mpz_ptr) mp_apint; |
---|
51 | #ifdef MP_DEBUG |
---|
52 | fprintf(stderr, "IMP_PutGmpInt: entering\n"); fflush(stderr); |
---|
53 | #endif |
---|
54 | |
---|
55 | if (!IMP_PutLong(link, (long *)&(apint->_mp_size))) |
---|
56 | return MP_SetError(link, MP_CantPutDataPacket); |
---|
57 | |
---|
58 | if (apint->_mp_size != 0) |
---|
59 | return IMP_PutUint32Vector(link, apint->_mp_d, |
---|
60 | (apint->_mp_size < 0 ? |
---|
61 | (- apint->_mp_size) : apint->_mp_size)); |
---|
62 | else |
---|
63 | return MP_ClearError(link); |
---|
64 | } |
---|
65 | |
---|
66 | |
---|
67 | |
---|
68 | #ifdef __STDC__ |
---|
69 | MP_Status_t IMP_GetGmpInt(MP_Link_pt link, MP_ApInt_t *mp_apint) |
---|
70 | #else |
---|
71 | MP_Status_t IMP_GetGmpInt(link, mp_apint) |
---|
72 | MP_Link_pt link; |
---|
73 | MP_ApInt_t *mp_apint; |
---|
74 | #endif |
---|
75 | { |
---|
76 | long int size; |
---|
77 | mp_ptr dp; |
---|
78 | mpz_ptr apint; |
---|
79 | if (*mp_apint == NULL) |
---|
80 | { |
---|
81 | *mp_apint = (MP_ApInt_t) IMP_MemAllocFnc(sizeof(*apint)); |
---|
82 | apint = (mpz_ptr) *mp_apint; |
---|
83 | mpz_init(apint); |
---|
84 | } |
---|
85 | else |
---|
86 | { |
---|
87 | apint = (mpz_ptr) *mp_apint; |
---|
88 | } |
---|
89 | |
---|
90 | if (!IMP_GetLong(link, &size)) |
---|
91 | return MP_SetError(link, MP_CantGetDataPacket); |
---|
92 | |
---|
93 | apint->_mp_size = size; |
---|
94 | if (size < 0) |
---|
95 | size = -size; |
---|
96 | _mpz_realloc(apint, size); |
---|
97 | apint->_mp_alloc = size; |
---|
98 | |
---|
99 | dp = apint->_mp_d; |
---|
100 | if (size != 0) |
---|
101 | return IMP_GetUint32Vector(link, &(apint->_mp_d), size); |
---|
102 | else |
---|
103 | return MP_ClearError(link); |
---|
104 | } |
---|
105 | |
---|
106 | #ifdef __STDC__ |
---|
107 | char * IMP_GmpIntToStr(MP_ApInt_t mp_apint, char *buffer) |
---|
108 | #else |
---|
109 | char * IMP_GmpIntToStr(mp_apint, buffer) |
---|
110 | MP_ApInt_t mp_apint; |
---|
111 | char *buffer; |
---|
112 | #endif |
---|
113 | { |
---|
114 | mpz_get_str(buffer, 10, (mpz_ptr) mp_apint); |
---|
115 | return buffer; |
---|
116 | } |
---|
117 | |
---|
118 | #ifdef __STDC__ |
---|
119 | long IMP_GmpIntAsciiSize(MP_ApInt_t mp_apint) |
---|
120 | #else |
---|
121 | long IMP_GmpIntAsciiSize(apint) |
---|
122 | MP_ApInt_t mp_apint; |
---|
123 | #endif |
---|
124 | { |
---|
125 | return mpz_sizeinbase((mpz_ptr) mp_apint, 10) + 2; |
---|
126 | } |
---|
127 | |
---|
128 | #endif /* MP_HAVE_GMP_APINT */ |
---|