Annotation of OpenXM/src/ox_toolkit/gmp_fake.c, Revision 1.1
1.1 ! ohara 1: /* -*- mode: C; coding: euc-japan -*- */
! 2: /* $OpenXM$ */
! 3:
! 4: #include <stdio.h>
! 5: #include <stdlib.h>
! 6: #include <string.h>
! 7: #include <ctype.h>
! 8: #include "gmp_fake.h"
! 9:
! 10: #define DEFAULT_LIMB_SIZE 1
! 11: #define MALLOC(x) malloc((x))
! 12: #define FREE(x) free((x))
! 13:
! 14: #if !defined(CHAR_BIT)
! 15: #define CHAR_BIT 8
! 16: #endif
! 17:
! 18: #define HAVE_UNSIGNED_LONG_LONG
! 19:
! 20: #if defined(HAVE_UNSIGNED_LONG_LONG)
! 21: typedef unsigned long long ulong64;
! 22: #elif defined(SIZEOF_LONG) && SIZEOF_LONG == 8
! 23: typedef unsigned long ulong64;
! 24: #endif
! 25:
! 26: #define RADIUS ((ulong64)1 << ((CHAR_BIT)*sizeof(mp_limb_t)))
! 27: #define LL_HIGH(x) ((x)>>((CHAR_BIT)*sizeof(mp_limb_t)))
! 28: #define LL_LOW(x) ((x) & ((RADIUS)-1))
! 29:
! 30: inline static void __mpz_clear(mpz_ptr z)
! 31: {
! 32: int size = abs(z->_mp_size);
! 33: z->_mp_size = size;
! 34: memset(z->_mp_d, 0, sizeof(mp_limb_t)*size);
! 35: }
! 36:
! 37: void *_mpz_realloc(mpz_ptr z, size_t n)
! 38: {
! 39: FREE(z->_mp_d);
! 40: z->_mp_size = n;
! 41: return z->_mp_d = MALLOC(n*sizeof(mp_limb_t));
! 42: }
! 43:
! 44: void mpz_init(mpz_ptr z)
! 45: {
! 46: z->_mp_size = DEFAULT_LIMB_SIZE;
! 47: z->_mp_d = MALLOC(DEFAULT_LIMB_SIZE);
! 48: __mpz_clear(z);
! 49: }
! 50:
! 51: void mpz_init_set(mpz_ptr z, mpz_ptr src)
! 52: {
! 53: mpz_init(z);
! 54: mpz_set(z, src);
! 55: }
! 56:
! 57: void mpz_set_si(mpz_ptr z, int i)
! 58: {
! 59: __mpz_clear(z);
! 60: z->_mp_size = (i < 0)? -z->_mp_size: z->_mp_size;
! 61: z->_mp_d[0] = abs(i);
! 62: }
! 63:
! 64: void mpz_set(mpz_ptr dest, mpz_ptr src)
! 65: {
! 66: int dsize=abs(dest->_mp_size);
! 67: int ssize=abs(src->_mp_size);
! 68: if (dsize < ssize) {
! 69: _mpz_realloc(dest, ssize);
! 70: dest->_mp_size = src->_mp_size;
! 71: }else {
! 72: __mpz_clear(dest);
! 73: dest->_mp_size = (src->_mp_size < 0)? -dsize: dsize;
! 74: }
! 75: memcpy(dest->_mp_d, src->_mp_d, ssize*sizeof(mp_limb_t));
! 76: }
! 77:
! 78: inline static void __mpz_neg(mpz_ptr z)
! 79: {
! 80: z->_mp_size *= -1;
! 81: }
! 82:
! 83: void mpz_neg(mpz_ptr dest, mpz_ptr src)
! 84: {
! 85: mpz_set(dest, src);
! 86: __mpz_neg(dest);
! 87: }
! 88:
! 89: int mpz_init_set_str(mpz_ptr z, char *nptr, int base)
! 90: {
! 91: mpz_init(z);
! 92: mpz_set_str(z, nptr, base);
! 93: return 0;
! 94: }
! 95:
! 96: /* base admits 0, 8, 10, or 16 */
! 97: char *mpz_get_str(char *s, int base, mpz_ptr src)
! 98: {
! 99: mpz_t z;
! 100: int i, j, len;
! 101: mp_limb_t res;
! 102: char *t;
! 103: ulong64 uu;
! 104:
! 105: if (base != 10 && base != 16 && base != 8) {
! 106: base = 10;
! 107: }
! 108: /* log2(8)=3 < log2(10) < log2(16)=4 */
! 109: len = ((CHAR_BIT)*sizeof(mp_limb_t)*abs(src->_mp_size))/((base==16)? 4: 3)+4;
! 110: mpz_init(z);
! 111: mpz_set(z, src);
! 112: t = MALLOC(len+1);
! 113: t[len] = '\0';
! 114: for(i=len-1; i>=0; i--) {
! 115: res = 0;
! 116: /* res := z % base, z := z / base */
! 117: for(j=abs(z->_mp_size)-1; j>=0; j--) {
! 118: uu = RADIUS*res + z->_mp_d[j];
! 119: res = uu % base;
! 120: z->_mp_d[j] = uu / base;
! 121: }
! 122: t[i] = res + ((res < 10)? '0' : ('a'-10));
! 123: }
! 124: /* skip 0's */
! 125: while (t[++i] == '0') {
! 126: }
! 127: if (t[i] == '\0' || base == 8) {
! 128: t[--i] = '0';
! 129: }else if (base == 16){
! 130: t[--i] = 'x';
! 131: t[--i] = '0';
! 132: }
! 133: if (src->_mp_size < 0) {
! 134: t[--i] = '-';
! 135: }
! 136: len = strlen(t+i)+1;
! 137: if (s == NULL) {
! 138: s = MALLOC(len);
! 139: }
! 140: memcpy(s, t+i, len);
! 141: FREE(t);
! 142: return s;
! 143: }
! 144:
! 145: int mpz_get_si(mpz_ptr z)
! 146: {
! 147: return (z->_mp_size < 0)? - z->_mp_d[0]: z->_mp_d[0];
! 148: }
! 149:
! 150: /* base admits 0, 8, 10, or 16 */
! 151: int mpz_set_str(mpz_ptr z, char *s, int base)
! 152: {
! 153: unsigned char c;
! 154: int neg = 0;
! 155: int len, i, size;
! 156: mp_limb_t res;
! 157: ulong64 uu;
! 158: char *t = s;
! 159:
! 160: do {
! 161: c = *t++;
! 162: } while (isspace(c));
! 163: if (c == '-') {
! 164: neg = 1;
! 165: c = *t++;
! 166: }else if (c == '+') {
! 167: c = *t++;
! 168: }
! 169: if ((base == 0 || base == 16) &&
! 170: c == '0' && (*t == 'x' || *t == 'X')) {
! 171: c = t[1];
! 172: t += 2;
! 173: base = 16;
! 174: }
! 175: if (base == 0) {
! 176: base = (c == '0')? 8: 10;
! 177: }
! 178: __mpz_clear(z);
! 179: /* log2(8)=3 < log2(10) < log2(16)=4 */
! 180: len = (((base == 8)? 3: 4)*(strlen(t)+1))/((CHAR_BIT)*sizeof(mp_limb_t))+1;
! 181: _mpz_realloc(z, len);
! 182:
! 183: for( ;; c = *t++) {
! 184: if (isdigit(c)) {
! 185: c -= '0';
! 186: }else if (isalpha(c)) {
! 187: c -= isupper(c)? ('A'-10): ('a'-10);
! 188: }else {
! 189: break;
! 190: }
! 191: if (c >= base) {
! 192: break;
! 193: }
! 194: size = abs(z->_mp_size);
! 195: res = c;
! 196: /* z := z*base + c */
! 197: for(i=0; i<size; i++) {
! 198: uu = ((ulong64)z->_mp_d[i])*base+res;
! 199: res = LL_HIGH(uu);
! 200: z->_mp_d[i] = LL_LOW(uu);
! 201: }
! 202: }
! 203: if (neg) {
! 204: __mpz_neg(z);
! 205: }
! 206: return 0;
! 207: }
! 208:
! 209: #ifdef DEBUG
! 210: void dump(mpz_ptr z)
! 211: {
! 212: int i;
! 213: int size = abs(z->_mp_size);
! 214: printf("_mp_size = %d\n_mp_d=%x", z->_mp_size, z->_mp_d[0]);
! 215: for(i=1; i<size; i++) {
! 216: printf(":%x", z->_mp_d[i]);
! 217: }
! 218: printf("\n");
! 219: }
! 220:
! 221: int main(int argc, char *argv[])
! 222: {
! 223: mpz_t z;
! 224: mpz_init(z);
! 225: mpz_set_str(z, argv[1], 0);
! 226: printf("%s\n", mpz_get_str(NULL, 10, z));
! 227: return 0;
! 228: }
! 229: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>