static Bigint *multadd(Bigint *b, int m, int a, Stack_alloc *alloc) { int i, wds; ULong *x; ULLong carry, y; Bigint *b1; wds= b->wds; x= b->p.x; i= 0; carry= a; do { y= *x * (ULLong)m + carry; carry= y >> 32; *x++= (ULong)(y & FFFFFFFF); } while (++i < wds); if (carry) { if (wds >= b->maxwds) { b1= Balloc(b->k+1, alloc); Bcopy(b1, b); Bfree(b, alloc); b= b1; } b->p.x[wds++]= (ULong) carry; b->wds= wds; } return b; }
strtoIxL(CONST char *s, char **sp, void *a, void *b) #endif { static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; Long exp[2]; Bigint *B[2]; int k, rv[2]; ULong *L = (ULong *)a, *M = (ULong *)b; B[0] = Balloc(1); B[0]->wds = 2; k = strtoIg(s, sp, &fpi, exp, B, rv); ULtoxL(L, B[0]->x, exp[0], rv[0]); Bfree(B[0]); if (B[1]) { ULtoxL(M, B[1]->x, exp[1], rv[1]); Bfree(B[1]); } else { M[0] = L[0]; M[1] = L[1]; M[2] = L[2]; } return k; }
// // multiply by m and add a // static Bigint * multadd(AllocatedBlock ** aBlocks, Bigint ** freelist, Bigint *b, int m, int a) { int i, wds; UINT_32 *x; UINT_64 carry, y; Bigint *b1; wds = b->wds; x = b->x; i = 0; carry = a; do { y = *x * (UINT_64)m + carry; carry = y >> 32; *x++ = (UINT_32)y & FFFFFFFF; } while(++i < wds); if (carry) { if (wds >= b->maxwds) { b1 = Balloc(aBlocks, freelist, b->k+1); Bcopy(b1, b); Bfree(freelist, b); b = b1; } b->x[wds++] = (UINT_32)carry; b->wds = wds; } return b; }
strtoId(CONST char *s, char **sp, double *f0, double *f1) #endif { static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; Long exp[2]; Bigint *B[2]; int k, rv[2]; B[0] = Balloc(1); if (B[0] == NULL) return STRTOG_NoMemory; B[0]->wds = 2; k = strtoIg(s, sp, &fpi, exp, B, rv); if (k == STRTOG_NoMemory) return k; ULtod((ULong*)f0, B[0]->x, exp[0], rv[0]); Bfree(B[0]); if (B[1]) { ULtod((ULong*)f1, B[1]->x, exp[1], rv[1]); Bfree(B[1]); } else { ((ULong*)f1)[0] = ((ULong*)f0)[0]; ((ULong*)f1)[1] = ((ULong*)f0)[1]; } return k; }
/** * Basic test for reallocation */ void test_Brealloc(void) { UBFH *p_ub = NULL; p_ub=Balloc(1, 30); assert_not_equal(p_ub, NULL); assert_equal(Badd(p_ub, T_STRING_FLD, BIG_TEST_STRING, 0), FAIL); assert_equal(Berror, BNOSPACE); /* Now reallocate, space should be bigger! */ p_ub=Brealloc(p_ub, 1, strlen(BIG_TEST_STRING)+1+2/* align */); assert_not_equal(p_ub, NULL); assert_equal(Badd(p_ub, T_STRING_FLD, BIG_TEST_STRING, 0), SUCCEED); /* should not allow to reallocate to 0! */ assert_equal(Brealloc(p_ub, 1, 0), NULL); assert_equal(Berror, BEINVAL); /* should be bigger than existing. */ assert_equal(Brealloc(p_ub, 1, strlen(BIG_TEST_STRING)+1), NULL); assert_equal(Berror, BEINVAL); assert_equal(SUCCEED, Bfree(p_ub)); }
/** * Test Balloc * @return */ void test_Balloc_Bfree(void) { UBFH *p_ub = NULL; int i; /* will check with valgrind - do we have memory leaks or not */ for (i=0; i<20; i++) { p_ub=Balloc(20, 30); assert_not_equal(p_ub, NULL); /* Put some data into memory so that we can test */ set_up_dummy_data(p_ub); do_dummy_data_test(p_ub); assert_equal(Bfree(p_ub), SUCCEED); } }
rv_alloc(int i) #endif { int j, k, *r; j = sizeof(ULong); for(k = 0; sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i; j <<= 1) k++; r = (int*)Balloc(k); *r = k; return #ifndef MULTIPLE_THREADS dtoa_result = #endif (char *)(r+1); }
strtoIf(CONST char *s, char **sp, float *f0, float *f1) #endif { static FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, SI }; Long exp[2]; Bigint *B[2]; int k, rv[2]; B[0] = Balloc(0); B[0]->wds = 1; k = strtoIg(s, sp, &fpi, exp, B, rv); ULtof((ULong*)f0, B[0]->x, exp[0], rv[0]); Bfree(B[0]); if (B[1]) { ULtof((ULong*)f1, B[1]->x, exp[1], rv[1]); Bfree(B[1]); } else *(ULong*)f1 = *(ULong*)f0; return k; }
rv_alloc(size_t i) #endif { size_t j; int k, *r; j = sizeof(ULong); for(k = 0; sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i; j <<= 1) k++; r = (int*)(void*)Balloc(k); if (r == NULL) return NULL; *r = k; return #ifndef MULTIPLE_THREADS dtoa_result = #endif (char *)(void *)(r+1); }
gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) #endif { Bigint *b; CONST unsigned char *decpt, *s0, *s, *s1; int esign, havedig, irv, k, n, nbits, up; ULong L, lostbits, *x; Long e, e1; #ifdef USE_LOCALE unsigned char decimalpoint = *localeconv()->decimal_point; #else #define decimalpoint '.' #endif #ifndef __SYMBIAN32__ if (!hexdig['0']) hexdig_init_D2A(); #endif //__SYMBIAN32__ havedig = 0; s0 = *(CONST unsigned char **)sp + 2; while(s0[havedig] == '0') havedig++; s0 += havedig; s = s0; decpt = 0; if (!hexdig[*s]) { if (*s == decimalpoint) { decpt = ++s; if (!hexdig[*s]) goto ret0; } else { ret0: *sp = (char*)s; return havedig ? STRTOG_Zero : STRTOG_NoNumber; } while(*s == '0') s++; havedig = 1; if (!hexdig[*s]) goto ret0; s0 = s; } while(hexdig[*s]) s++; if (*s == decimalpoint && !decpt) { decpt = ++s; while(hexdig[*s]) s++; } e = 0; if (decpt) e = -(((Long)(s-decpt)) << 2); s1 = s; switch(*s) { case 'p': case 'P': esign = 0; switch(*++s) { case '-': esign = 1; /* no break */ case '+': s++; } if ((n = hexdig[*s]) == 0 || n > 0x19) { s = s1; break; } e1 = n - 0x10; while((n = hexdig[*++s]) !=0 && n <= 0x19) e1 = 10*e1 + n - 0x10; if (esign) e1 = -e1; e += e1; } *sp = (char*)s; n = s1 - s0 - 1; for(k = 0; n > 7; n >>= 1) k++; b = Balloc(k); x = b->x; n = 0; L = 0; while(s1 > s0) { if (*--s1 == decimalpoint) continue; if (n == 32) { *x++ = L; L = 0; n = 0; } L |= (hexdig[*s1] & 0x0f) << n; n += 4; } *x++ = L; b->wds = n = x - b->x; n = 32*n - hi0bits(L); nbits = fpi->nbits; lostbits = 0; x = b->x; if (n > nbits) { n -= nbits; if (any_on(b,n)) { lostbits = 1; k = n - 1; if (x[k>>kshift] & 1 << (k & kmask)) { lostbits = 2; if (k > 1 && any_on(b,k-1)) lostbits = 3; } } rshift(b, n); e += n; }
strtoIg(CONST char *s00, char **se, FPI *fpi, Long *exp, Bigint **B, int *rvp) #endif { Bigint *b, *b1; int i, nb, nw, nw1, rv, rv1, swap; unsigned int nb1, nb11; Long e1; b = *B; rv = strtodg(s00, se, fpi, exp, b->x); if (rv == STRTOG_NoMemory) return rv; if (!(rv & STRTOG_Inexact)) { B[1] = 0; return *rvp = rv; } e1 = exp[0]; rv1 = rv ^ STRTOG_Inexact; b1 = Balloc(b->k); if (b1 == NULL) return STRTOG_NoMemory; Bcopy(b1, b); nb = fpi->nbits; nb1 = nb & 31; nb11 = (nb1 - 1) & 31; nw = b->wds; nw1 = nw - 1; if (rv & STRTOG_Inexlo) { swap = 0; b1 = increment(b1); if (fpi->sudden_underflow && (rv & STRTOG_Retmask) == STRTOG_Zero) { b1->x[0] = 0; b1->x[nw1] = 1L << nb11; rv1 += STRTOG_Normal - STRTOG_Zero; rv1 &= ~STRTOG_Underflow; goto swapcheck; } if (b1->wds > nw || nb1 && b1->x[nw1] & 1L << nb1) { if (++e1 > fpi->emax) rv1 = STRTOG_Infinite | STRTOG_Inexhi; rshift(b1, 1); } else if ((rv & STRTOG_Retmask) == STRTOG_Denormal) { if (b1->x[nw1] & 1L << nb11) { rv1 += STRTOG_Normal - STRTOG_Denormal; rv1 &= ~STRTOG_Underflow; } } } else { swap = STRTOG_Neg; if ((rv & STRTOG_Retmask) == STRTOG_Infinite) { b1 = set_ones(b1, nb); e1 = fpi->emax; rv1 = STRTOG_Normal | STRTOG_Inexlo; goto swapcheck; } decrement(b1); if ((rv & STRTOG_Retmask) == STRTOG_Denormal) { for(i = nw1; !b1->x[i]; --i) if (!i) { rv1 = STRTOG_Zero | STRTOG_Inexlo; break; } goto swapcheck; } if (!(b1->x[nw1] & 1L << nb11)) { if (e1 == fpi->emin) { if (fpi->sudden_underflow) rv1 += STRTOG_Zero - STRTOG_Normal; else rv1 += STRTOG_Denormal - STRTOG_Normal; rv1 |= STRTOG_Underflow; } else { b1 = lshift(b1, 1); b1->x[0] |= 1; --e1; } } } swapcheck: if (swap ^ (rv & STRTOG_Neg)) { rvp[0] = rv1; rvp[1] = rv; B[0] = b1; B[1] = b; exp[1] = exp[0]; exp[0] = e1; } else { rvp[0] = rv; rvp[1] = rv1; B[1] = b1; exp[1] = e1; } return rv; }
int gethex( CONST char **sp, CONST FPI *fpi, Long *expt, Bigint **bp, int sign) { Bigint *b; CONST unsigned char *decpt, *s0, *s, *s1; int esign, havedig, irv, k, n, nbits, up, zret; ULong L, lostbits, *x; Long e, e1; #ifdef USE_LOCALE unsigned char decimalpoint = *localeconv()->decimal_point; #else #define decimalpoint '.' #endif if (!hexdig['0']) hexdig_init_D2A(); havedig = 0; s0 = *(CONST unsigned char **)sp + 2; while(s0[havedig] == '0') havedig++; s0 += havedig; s = s0; decpt = 0; zret = 0; e = 0; if (!hexdig[*s]) { zret = 1; if (*s != decimalpoint) goto pcheck; decpt = ++s; if (!hexdig[*s]) goto pcheck; while(*s == '0') s++; if (hexdig[*s]) zret = 0; havedig = 1; s0 = s; } while(hexdig[*s]) s++; if (*s == decimalpoint && !decpt) { decpt = ++s; while(hexdig[*s]) s++; } if (decpt) e = -(((Long)(s-decpt)) << 2); pcheck: s1 = s; switch(*s) { case 'p': case 'P': esign = 0; switch(*++s) { case '-': esign = 1; /* FALLTHROUGH */ case '+': s++; } if ((n = hexdig[*s]) == 0 || n > 0x19) { s = s1; break; } e1 = n - 0x10; while((n = hexdig[*++s]) !=0 && n <= 0x19) e1 = 10*e1 + n - 0x10; if (esign) e1 = -e1; e += e1; } *sp = __UNCONST(s); if (zret) return havedig ? STRTOG_Zero : STRTOG_NoNumber; n = (int)(s1 - s0 - 1); for(k = 0; n > 7; n = (unsigned int)n >> 1) k++; b = Balloc(k); if (b == NULL) return STRTOG_NoMemory; x = b->x; n = 0; L = 0; while(s1 > s0) { if (*--s1 == decimalpoint) continue; if (n == 32) { *x++ = L; L = 0; n = 0; } L |= (hexdig[*s1] & 0x0f) << n; n += 4; } *x++ = L; b->wds = n = (int)(x - b->x); n = 32*n - hi0bits(L); nbits = fpi->nbits; lostbits = 0; x = b->x; if (n > nbits) { n -= nbits; if (any_on(b,n)) { lostbits = 1; k = n - 1; if (x[(unsigned int)k>>kshift] & 1 << (k & kmask)) { lostbits = 2; if (k > 1 && any_on(b,k-1)) lostbits = 3; } } rshift(b, n); e += n; }
#if defined(IEEE_Arith) + defined(VAX) if ((word0(d) & Exp_mask) == Exp_mask) #else if (word0(d) == 0x8000) #endif { /* Infinity or NaN */ *decpt = 9999; s = #ifdef IEEE_Arith !word1(d) && !(word0(d) & 0xfffff) ? "Infinity" : #endif "NaN"; result = Balloc(strlen(s)+1); if (result == BIGINT_INVALID) return NULL; s0 = (char *)(void *)result; strcpy(s0, s); if (rve) *rve = #ifdef IEEE_Arith s0[3] ? s0 + 8 : #endif s0 + 3; return s0; }
gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) #endif { Bigint *b; CONST unsigned char *decpt, *s0, *s, *s1; int big, esign, havedig, irv, j, k, n, n0, nbits, up, zret; ULong L, lostbits, *x; Long e, e1; #ifdef USE_LOCALE int i; #ifdef NO_LOCALE_CACHE const unsigned char *decimalpoint = (unsigned char*)localeconv()->decimal_point; #else const unsigned char *decimalpoint; static unsigned char *decimalpoint_cache; if (!(s0 = decimalpoint_cache)) { s0 = (unsigned char*)localeconv()->decimal_point; if ((decimalpoint_cache = (char*)malloc(strlen(s0) + 1))) { strcpy(decimalpoint_cache, s0); s0 = decimalpoint_cache; } } decimalpoint = s0; #endif #endif if (!hexdig['0']) hexdig_init_D2A(); *bp = 0; havedig = 0; s0 = *(CONST unsigned char **)sp + 2; while(s0[havedig] == '0') havedig++; s0 += havedig; s = s0; decpt = 0; zret = 0; e = 0; if (hexdig[*s]) havedig++; else { zret = 1; #ifdef USE_LOCALE for(i = 0; decimalpoint[i]; ++i) { if (s[i] != decimalpoint[i]) goto pcheck; } decpt = s += i; #else if (*s != '.') goto pcheck; decpt = ++s; #endif if (!hexdig[*s]) goto pcheck; while(*s == '0') s++; if (hexdig[*s]) zret = 0; havedig = 1; s0 = s; } while(hexdig[*s]) s++; #ifdef USE_LOCALE if (*s == *decimalpoint && !decpt) { for(i = 1; decimalpoint[i]; ++i) { if (s[i] != decimalpoint[i]) goto pcheck; } decpt = s += i; #else if (*s == '.' && !decpt) { decpt = ++s; #endif while(hexdig[*s]) s++; }/*}*/ if (decpt) e = -(((Long)(s-decpt)) << 2); pcheck: s1 = s; big = esign = 0; switch(*s) { case 'p': case 'P': switch(*++s) { case '-': esign = 1; /* no break */ case '+': s++; } if ((n = hexdig[*s]) == 0 || n > 0x19) { s = s1; break; } e1 = n - 0x10; while((n = hexdig[*++s]) !=0 && n <= 0x19) { if (e1 & 0xf8000000) big = 1; e1 = 10*e1 + n - 0x10; } if (esign) e1 = -e1; e += e1; } *sp = (char*)s; if (!havedig) *sp = (char*)s0 - 1; if (zret) return STRTOG_Zero; if (big) { if (esign) { switch(fpi->rounding) { case FPI_Round_up: if (sign) break; goto ret_tiny; case FPI_Round_down: if (!sign) break; goto ret_tiny; } goto retz; ret_tiny: b = Balloc(0); b->wds = 1; b->x[0] = 1; goto dret; } switch(fpi->rounding) { case FPI_Round_near: goto ovfl1; case FPI_Round_up: if (!sign) goto ovfl1; goto ret_big; case FPI_Round_down: if (sign) goto ovfl1; goto ret_big; } ret_big: nbits = fpi->nbits; n0 = n = nbits >> kshift; if (nbits & kmask) ++n; for(j = n, k = 0; j >>= 1; ++k); *bp = b = Balloc(k); b->wds = n; for(j = 0; j < n0; ++j) b->x[j] = ALL_ON; if (n > n0) b->x[j] = ULbits >> (ULbits - (nbits & kmask)); *exp = fpi->emin; return STRTOG_Normal | STRTOG_Inexlo; } n = s1 - s0 - 1; for(k = 0; n > 7; n >>= 1) k++; b = Balloc(k); x = b->x; n = 0; L = 0; #ifdef USE_LOCALE for(i = 0; decimalpoint[i+1]; ++i); #endif while(s1 > s0) { #ifdef USE_LOCALE if (*--s1 == decimalpoint[i]) { s1 -= i; continue; } #else if (*--s1 == '.') continue; #endif if (n == 32) { *x++ = L; L = 0; n = 0; } L |= (hexdig[*s1] & 0x0f) << n; n += 4; } *x++ = L; b->wds = n = x - b->x; n = 32*n - hi0bits(L); nbits = fpi->nbits; lostbits = 0; x = b->x; if (n > nbits) { n -= nbits; if (any_on(b,n)) { lostbits = 1; k = n - 1; if (x[k>>kshift] & 1 << (k & kmask)) { lostbits = 2; if (k > 0 && any_on(b,k)) lostbits = 3; } } rshift(b, n); e += n; } else if (n < nbits) {