Ejemplo n.º 1
0
 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;
    }
Ejemplo n.º 2
0
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;
		}
Ejemplo n.º 3
0
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) {