Example #1
0
static struct xpr
rred (struct xpr z, int kf, int *ps)
{
  struct xpr is, q;

  if (x_neg (&z))
    {
      z = xneg (z);
      is = xOne;
    }
  else
    is = xZero;
  z = xfmod (z, xPi, &q);
  if (kf == 't')
    q = is;
  else if (kf == 's')
    q = xadd (q, is, 0);
  if (xprcmp (&z, &xPi2) == 1)
    {
      z = xadd (xPi, z, 1);
      if (kf == 'c' || kf == 't')
	q = xadd (q, xOne, 0);
    }
  *ps = (xodd (q)) ? 1 : 0;
  return z;
}
Example #2
0
struct xpr
cxarg (struct cxpr z)
{
  int rs, is;

  rs = xsgn (&z.re);
  is = xsgn (&z.im);
  if (rs > 0)
    return xatan (xdiv (z.im, z.re));
  else if (rs < 0)
    {
      z.re.nmm[0] ^= xM_sgn;
      z.im.nmm[0] ^= xM_sgn;
      if (is >= 0)
	return xadd (xPi, xatan (xdiv (z.im, z.re)), 0);
      else
	return xadd (xatan (xdiv (z.im, z.re)), xPi, 1);
    }
  else				/* z.re is zero ! */
    {
      if (!xsigerr (is == 0, XEDOM, "cxarg()"))
	return (is > 0 ? xPi2 : xneg (xPi2));
      else
	return xneg (xPi2);	/* Dummy value :) */
    }
}
Example #3
0
int
main (int na, char **av)
{
  struct xpr s, t, f;
  char nbx[64], nby[64];
  FILE *fp;

  if (na != 2)
    {
      printf ("para: input_file\n");
      exit (-1);
    }
  fp = fopen (*++av, "r");
  printf ("     Test of Elementary Operations\n");
  while (fscanf (fp, "%s %s", nbx, nby) != EOF)
    {
      s = atox (nbx);
      t = atox (nby);
      printf ("\n x= ");
      xprxpr (s, decd);
      printf ("\n y= ");
      xprxpr (t, decd);

      /* extended precision addition */
      printf ("\nadd\n");
      f = xadd (s, t, 0);
      printf (" %16.10f\n", xtodbl (f));
      xprxpr (f, decd);

      /* extended precision subtraction */
      printf ("\nsubtract\n");
      f = xadd (s, t, 1);
      printf (" %16.10f\n", xtodbl (f));
      xprxpr (f, decd);

      /* extended precision multiplication */
      printf ("\nmultiply\n");
      f = xmul (s, t);
      printf (" %16.10f\n", xtodbl (f));
      xprxpr (f, decd);

      /* extended precision division */
      printf ("\ndivide\n");
      f = xdiv (s, t);
      printf (" %16.10f\n", xtodbl (f));
      xprxpr (f, decd);
    }
  putchar ('\n');
  return 0;
}
Example #4
0
void
runtime·entersyscall(void)
{
	uint32 v;

	if(m->profilehz > 0)
		runtime·setprof(false);

	// Leave SP around for gc and traceback.
	runtime·gosave(&g->sched);
	g->gcsp = g->sched.sp;
	g->gcstack = g->stackbase;
	g->gcguard = g->stackguard;
	g->status = Gsyscall;
	if(g->gcsp < g->gcguard-StackGuard || g->gcstack < g->gcsp) {
		// runtime·printf("entersyscall inconsistent %p [%p,%p]\n",
		//	g->gcsp, g->gcguard-StackGuard, g->gcstack);
		runtime·throw("entersyscall");
	}

	// Fast path.
	// The slow path inside the schedlock/schedunlock will get
	// through without stopping if it does:
	//	mcpu--
	//	gwait not true
	//	waitstop && mcpu <= mcpumax not true
	// If we can do the same with a single atomic add,
	// then we can skip the locks.
	v = runtime·xadd(&runtime·sched.atomic, -1<<mcpuShift);
	if(!atomic_gwaiting(v) && (!atomic_waitstop(v) || atomic_mcpu(v) > atomic_mcpumax(v)))
		return;

	schedlock();
	v = runtime·atomicload(&runtime·sched.atomic);
	if(atomic_gwaiting(v)) {
		matchmg();
		v = runtime·atomicload(&runtime·sched.atomic);
	}
	if(atomic_waitstop(v) && atomic_mcpu(v) <= atomic_mcpumax(v)) {
		runtime·xadd(&runtime·sched.atomic, -1<<waitstopShift);
		runtime·notewakeup(&runtime·sched.stopped);
	}

	// Re-save sched in case one of the calls
	// (notewakeup, matchmg) triggered something using it.
	runtime·gosave(&g->sched);

	schedunlock();
}
Example #5
0
struct xpr
cxabs (struct cxpr z)
{
  struct xpr x;
  int ea, eb;

  if (xprcmp (&z.re, &xZero) == 0 && xprcmp (&z.im, &xZero) == 0)
    return xZero;
  else
    {
      ea = (z.re.nmm[0] &= xM_exp) - xBias;
      eb = (z.im.nmm[0] &= xM_exp) - xBias;
      if (ea > eb + XBOUND)
	return z.re;
      else if (eb > ea + XBOUND)
	return z.im;
      else
	{
	  z.re.nmm[0] -= eb;
	  z.im.nmm[0] = xBias;
	  x = xsqrt (xadd (xmul (z.re, z.re), xmul (z.im, z.im), 0));
	  x.nmm[0] += eb;
	  return x;
	}
    }
}
Example #6
0
struct xpr
xtan (struct xpr z)
{
  int k, m;

  z = rred (z, 't', &k);
  if ((xsigerr (xprcmp (&z, &xPi2) >= 0, XEDOM, "xtan()")))
    return (!k ? xPinf : xMinf);
  else
    {
      if (xprcmp (&z, &xPi4) == 1)
	{
	  m = 1;
	  z = xadd (xPi2, z, 1);
	}
      else
	m = 0;
      if ((k))
	z = xneg (c_tan (z));
      else
	z = c_tan (z);
      if (m)
	return xdiv (xOne, z);
      else
	return z;
    }
}
Example #7
0
int
main (void)
{
  struct xpr z, h, f, u;

  printf ("     Test of Exp Functions\n");
  z = xneg (xOne);
  h = atox ("0.5");
  u = atox ("3.01");
  for (; xprcmp (&z, &u) < 0; z = xadd (z, h, 0))
    {
      /* compute extended precision exponential */
      f = xexp (z);
      printf (" %8.4f  ", xtodbl (z));
      xprxpr (f, decd);
      f = xexp2 (z);
      printf ("\n           ");
      xprxpr (f, decd);
      f = xexp10 (z);
      printf ("\n           ");
      xprxpr (f, decd);
      putchar ('\n');
    }
  return 0;
}
Example #8
0
void
runtime·dopanic(int32 unused)
{
	static bool didothers;

	if(g->sig != 0)
		runtime·printf("[signal %x code=%p addr=%p pc=%p]\n",
			g->sig, g->sigcode0, g->sigcode1, g->sigpc);

	if(runtime·gotraceback()){
		if(g != m->g0) {
			runtime·printf("\n");
			runtime·goroutineheader(g);
			runtime·traceback(runtime·getcallerpc(&unused), runtime·getcallersp(&unused), 0, g);
		}
		if(!didothers) {
			didothers = true;
			runtime·tracebackothers(g);
		}
	}
	runtime·unlock(&paniclk);
	if(runtime·xadd(&runtime·panicking, -1) != 0) {
		// Some other m is panicking too.
		// Let it print what it needs to print.
		// Wait forever without chewing up cpu.
		// It will exit when it's done.
		static Lock deadlock;
		runtime·lock(&deadlock);
		runtime·lock(&deadlock);
	}

	runtime·exit(2);
}
Example #9
0
// Put on `g' queue.  Sched must be locked.
static void
gput(G *g)
{
	M *m;

	// If g is wired, hand it off directly.
	if((m = g->lockedm) != nil && canaddmcpu()) {
		mnextg(m, g);
		return;
	}

	// If g is the idle goroutine for an m, hand it off.
	if(g->idlem != nil) {
		if(g->idlem->idleg != nil) {
			runtime·printf("m%d idle out of sync: g%d g%d\n",
				g->idlem->id,
				g->idlem->idleg->goid, g->goid);
			runtime·throw("runtime: double idle");
		}
		g->idlem->idleg = g;
		return;
	}

	g->schedlink = nil;
	if(runtime·sched.ghead == nil)
		runtime·sched.ghead = g;
	else
		runtime·sched.gtail->schedlink = g;
	runtime·sched.gtail = g;

	// increment gwait.
	// if it transitions to nonzero, set atomic gwaiting bit.
	if(runtime·sched.gwait++ == 0)
		runtime·xadd(&runtime·sched.atomic, 1<<gwaitingShift);
}
Example #10
0
int
cxrec (struct cxpr z, struct cxpr *w)
{
  struct xpr x;
  int sa, sb, ea, eb;

  if (xprcmp (&z.re, &xZero) == 0 && xprcmp (&z.im, &xZero) == 0)
    return 0;
  else
    {
      sa = z.re.nmm[0] & xM_sgn;
      sb = z.im.nmm[0] & xM_sgn;
      ea = (z.re.nmm[0] &= xM_exp) - xBias;
      eb = (z.im.nmm[0] &= xM_exp) - xBias;
      if (ea > eb + XBOUND)
	x = z.re;
      else if (eb > ea + XBOUND)
	x = z.im;
      else
	{
	  z.re.nmm[0] -= eb;
	  z.im.nmm[0] = xBias;
	  x = xsqrt (xadd (xmul (z.re, z.re), xmul (z.im, z.im), 0));
	  x.nmm[0] += eb;
	  z.re.nmm[0] += eb;
	  z.im.nmm[0] += eb;
	}
      w->re = xdiv (xdiv (z.re, x), x);
      w->im = xdiv (xdiv (z.im, x), x);
      w->re.nmm[0] |= sa;
      w->im.nmm[0] |= xM_sgn ^ sb;
      return 1;
    }
}
Example #11
0
// User-level semaphore implementation:
// try to do the operations in user space on u,
// but when it's time to block, fall back on the kernel semaphore k.
// This is the same algorithm used in Plan 9.
void
usemacquire(Usema *s)
{
	if((int32)xadd(&s->u, -1) < 0) {
		if(s->k == 0)
			initsema(&s->k);
		mach_semacquire(s->k);
	}
}
Example #12
0
void
usemrelease(Usema *s)
{
	if((int32)xadd(&s->u, 1) <= 0) {
		if(s->k == 0)
			initsema(&s->k);
		mach_semrelease(s->k);
	}
}
Example #13
0
void
canonic_form (struct xpr *px)
{
  unsigned short *p, u;
  short e, i, j, skip;

  p = (unsigned short *) px;
  e = (*p & xM_exp);		/* biased exponent of x */
  u = (*p & xM_sgn);		/* sign of x            */
  if (e < xBias - 1)
    return;
  else
    {
      unsigned short mask = 0xffff;

      /* e >= xBias - 1 */
      for (i = 1, skip = e + 1 - xBias; skip / 16 > 0; i++, skip -= 16);
      if (i <= XDIM)
	{
	  /* skip = 0, ..., 15 */
	  mask >>= skip;
	  if ((p[i] & mask) != mask)
	    return;
	  else
	    {
	      for (j = i + 1; j <= XDIM && p[j] == 0xffff; j++);
	      if (j > XDIM)
		{
		  p[i] -= mask;
		  for (j = i + 1; j <= XDIM; p[j] = 0, j++);
		  if (!(p[1] & 0x8000))
		    {
		      p[1] = 0x8000;
		      *p = ++e;
		      *p |= u;
		    }
		  else if ((u))
		    *px = xadd (*px, xOne, 1);
		  else
		    *px = xadd (*px, xOne, 0);
		}
	    }
	}			/* end   if(i <= XDIM ) */
    }				/* end outer else */
Example #14
0
static void
eventlock(Lock *l)
{
	// Allocate event if needed.
	if(l->event == 0)
		initevent(&l->event);

	if(xadd(&l->key, 1) > 1)	// someone else has it; wait
		stdcall(WaitForSingleObject, l->event, -1);
}
Example #15
0
static void
eventlock(Lock *l)
{
	// Allocate event if needed.
	if(l->event == 0)
		initevent(&l->event);

	if(runtime·xadd(&l->key, 1) > 1)	// someone else has it; wait
		runtime·stdcall(runtime·WaitForSingleObject, 2, l->event, (uintptr)-1);
}
Example #16
0
int
main (void)
{
  struct xpr z, w, f, u;
  int k;
  char cf[3];

  cf[0] = 's';
  cf[1] = 'c';
  cf[2] = 't';
  for (k = 0; k < 3; ++k)
    {
      switch (cf[k])
	{
	case 't':
	  printf ("     Test of Atanh Function\n");
	  break;
	case 's':
	  printf ("     Test of Asinh Function\n");
	  break;
	case 'c':
	  printf ("     Test of Acosh Function\n");
	  break;
	}
      z = atox ("-3.10");
      w = atox ("0.2");
      u = atox ("3");
      for (; xprcmp (&z, &u) < 0; z = xadd (z, w, 0))
	{
	  xErrNo = 0;
	  /* compute selected extended precision hyperbolic function */
	  switch (cf[k])
	    {
	    case 't':
	      f = xatanh (z);
	      break;
	    case 's':
	      f = xasinh (z);
	      break;
	    case 'c':
	      f = xacosh (z);
	      break;
	    }
	  if (!xErrNo)
	    {
	      printf (" %8.4f  ", xtodbl (z));
	      xprxpr (f, decd);
	      putchar ('\n');
	    }
	  else
	    printf ("*** Out of range\n");
	}
    }
  return 0;
}
Example #17
0
void
runtime·startpanic(void)
{
	if(m->dying) {
		runtime·printf("panic during panic\n");
		runtime·exit(3);
	}
	m->dying = 1;
	runtime·xadd(&runtime·panicking, 1);
	runtime·lock(&paniclk);
}
Example #18
0
struct xpr
xcos (struct xpr z)
{
  int k;

  z = rred (z, 'c', &k);
  if (x_exp (&z) < xK_lin)
    {
      if ((k))
	return xneg (xOne);
      else
	return xOne;
    }
  z = c_tan (xpr2 (z, -1));
  z = xmul (z, z);
  z = xdiv (xadd (xOne, z, 1), xadd (xOne, z, 0));
  if ((k))
    return xneg (z);
  else
    return z;
}
Example #19
0
void
lock(Lock *l)
{
	if(m->locks < 0)
		throw("lock count");
	m->locks++;

	if(xadd(&l->key, 1) > 1) {	// someone else has it; wait
		// Allocate semaphore if needed.
		if(l->sema == 0)
			initsema(&l->sema);
		mach_semacquire(l->sema);
	}
}
Example #20
0
void
unlock(Lock *l)
{
	m->locks--;
	if(m->locks < 0)
		throw("lock count");

	if(xadd(&l->key, -1) > 0) {	// someone else is waiting
		// Allocate semaphore if needed.
		if(l->sema == 0)
			initsema(&l->sema);
		mach_semrelease(l->sema);
	}
}
int adjacent_to (int board[][BOARD_HEIGHT], int i, int j) {
	int	k, l, count;

	count = 0;

	/* go around the cell */

	for (k=-1; k<=1; k++) for (l=-1; l<=1; l++)

		/* only count if at least one of k,l isn't zero */

		if (k || l)
			if (board[xadd(i,k)][yadd(j,l)]) count++;
	return count;
}
Example #22
0
static struct xpr
c_tan (struct xpr z)
{
  struct xpr s, f, d;
  int m;
  unsigned short k;

  if (x_exp (&z) < xK_lin)
    return z;
  s = xneg (xmul (z, z));
  for (k = 1; k <= XDIM && s.nmm[k] == 0; k++);
  if ((xsigerr (s.nmm[0] == 0xffff && k > XDIM, XFPOFLOW, NULL)))
    return xZero;
  else
    {
      f = xZero;
      for (d = inttox (m = xMS_trg); m > 1;)
	{
	  f = xdiv (s, xadd (d, f, 0));
	  d = inttox (m -= 2);
	}
      return xdiv (z, xadd (d, f, 0));
    }
}
Example #23
0
struct xpr
xsin (struct xpr z)
{
  int k;

  z = rred (z, 's', &k);
  if (x_exp (&z) >= xK_lin)
    {
      z = c_tan (xpr2 (z, -1));
      z = xdiv (xpr2 (z, 1), xadd (xOne, xmul (z, z), 0));
    }
  if ((k))
    return xneg (z);
  else
    return z;
}
Example #24
0
void
runtime·startpanic(void)
{
	if(runtime·mheap == 0 || runtime·mheap->cachealloc.size == 0) { // very early
		runtime·printf("runtime: panic before malloc heap initialized\n");
		m->mallocing = 1; // tell rest of panic not to try to malloc
	} else if(m->mcache == nil) // can happen if called from signal handler or throw
		m->mcache = runtime·allocmcache();
	if(m->dying) {
		runtime·printf("panic during panic\n");
		runtime·exit(3);
	}
	m->dying = 1;
	runtime·xadd(&runtime·panicking, 1);
	runtime·lock(&paniclk);
}
Example #25
0
struct cxpr
cxatanh (struct cxpr z)
{
  struct cxpr w;
  struct xpr t;
  int errcond;

  t = xadd (xabs (z.re), xOne, 1);
  errcond = xsgn (&z.im) == 0 && xsgn (&t) == 0;
  if (xsigerr (errcond, XEDOM, "cxatanh()"))
    return cxZero;
  else
    {
      w = cxdiv (cxsum (cxOne, z), cxsub (cxOne, z));
      w = cxlog_sqrt (w);
      return w;
    }
}
Example #26
0
// The goroutine g exited its system call.
// Arrange for it to run on a cpu again.
// This is called only from the go syscall library, not
// from the low-level system calls used by the runtime.
void
runtime·exitsyscall(void)
{
	uint32 v;

	// Fast path.
	// If we can do the mcpu++ bookkeeping and
	// find that we still have mcpu <= mcpumax, then we can
	// start executing Go code immediately, without having to
	// schedlock/schedunlock.
	v = runtime·xadd(&runtime·sched.atomic, (1<<mcpuShift));
	if(m->profilehz == runtime·sched.profilehz && atomic_mcpu(v) <= atomic_mcpumax(v)) {
		// There's a cpu for us, so we can run.
		g->status = Grunning;
		// Garbage collector isn't running (since we are),
		// so okay to clear gcstack.
		g->gcstack = nil;

		if(m->profilehz > 0)
			runtime·setprof(true);
		return;
	}

	// Tell scheduler to put g back on the run queue:
	// mostly equivalent to g->status = Grunning,
	// but keeps the garbage collector from thinking
	// that g is running right now, which it's not.
	g->readyonstop = 1;

	// All the cpus are taken.
	// The scheduler will ready g and put this m to sleep.
	// When the scheduler takes g away from m,
	// it will undo the runtime·sched.mcpu++ above.
	runtime·gosched();

	// Gosched returned, so we're allowed to run now.
	// Delete the gcstack information that we left for
	// the garbage collector during the system call.
	// Must wait until now because until gosched returns
	// we don't know for sure that the garbage collector
	// is not running.
	g->gcstack = nil;
}
Example #27
0
int
main (void)
{
    struct xpr z, w, f, u;

    printf ("     Test of Sqrt Function\n");
    z = xZero;
    w = atox ("0.2");
    u = atox ("4.01");
    for (; xprcmp (&z, &u) < 0; z = xadd (z, w, 0))
    {
        /* compute extended precision square root */
        f = xsqrt (z);
        printf (" %8.4f  ", xtodbl (z));
        xprxpr (f, decd);
        putchar ('\n');
    }
    return 0;
}
Example #28
0
// Get from `g' queue.  Sched must be locked.
static G*
gget(void)
{
	G *g;

	g = runtime·sched.ghead;
	if(g){
		runtime·sched.ghead = g->schedlink;
		if(runtime·sched.ghead == nil)
			runtime·sched.gtail = nil;
		// decrement gwait.
		// if it transitions to zero, clear atomic gwaiting bit.
		if(--runtime·sched.gwait == 0)
			runtime·xadd(&runtime·sched.atomic, -1<<gwaitingShift);
	} else if(m->idleg != nil) {
		g = m->idleg;
		m->idleg = nil;
	}
	return g;
}
Example #29
0
void
runtime·startpanic(void)
{
	if(runtime·mheap.cachealloc.size == 0) { // very early
		runtime·printf("runtime: panic before malloc heap initialized\n");
		m->mallocing = 1; // tell rest of panic not to try to malloc
	} else if(m->mcache == nil) // can happen if called from signal handler or throw
		m->mcache = runtime·allocmcache();
	switch(m->dying) {
	case 0:
		m->dying = 1;
		if(g != nil)
			g->writebuf = nil;
		runtime·xadd(&runtime·panicking, 1);
		runtime·lock(&paniclk);
		if(runtime·debug.schedtrace > 0 || runtime·debug.scheddetail > 0)
			runtime·schedtrace(true);
		runtime·freezetheworld();
		return;
	case 1:
		// Something failed while panicing, probably the print of the
		// argument to panic().  Just print a stack trace and exit.
		m->dying = 2;
		runtime·printf("panic during panic\n");
		runtime·dopanic(0);
		runtime·exit(3);
	case 2:
		// This is a genuine bug in the runtime, we couldn't even
		// print the stack trace successfully.
		m->dying = 3;
		runtime·printf("stack trace unavailable\n");
		runtime·exit(4);
	default:
		// Can't even print!  Just exit.
		runtime·exit(5);
	}
}
Example #30
0
static char*
xdodtoa(char *s1, double f, int chr, int prec, int *decpt, int *rsign)
{
	char s2[NSIGNIF+10];
	double g, h;
	int e, d, i;
	int c2, sign, oerr;

	if(chr == 'F')
		chr = 'f';
	if(prec > NSIGNIF)
		prec = NSIGNIF;
	if(prec < 0)
		prec = 0;
	if(__isNaN(f)) {
		*decpt = 9999;
		*rsign = 0;
		strcpy(s1, "nan");
		return &s1[3];
	}
	sign = 0;
	if(f < 0) {
		f = -f;
		sign++;
	}
	*rsign = sign;
	if(__isInf(f, 1) || __isInf(f, -1)) {
		*decpt = 9999;
		strcpy(s1, "inf");
		return &s1[3];
	}

	e = 0;
	g = f;
	if(g != 0) {
		frexp(f, &e);
		e = (int)(e * .301029995664);
		if(e >= -150 && e <= +150) {
			d = 0;
			h = f;
		} else {
			d = e/2;
			h = f * pow10(-d);
		}
		g = h * pow10(d-e);
		while(g < 1) {
			e--;
			g = h * pow10(d-e);
		}
		while(g >= 10) {
			e++;
			g = h * pow10(d-e);
		}
	}

	/*
	 * convert NSIGNIF digits and convert
	 * back to get accuracy.
	 */
	for(i=0; i<NSIGNIF; i++) {
		d = (int)g;
		s1[i] = d + '0';
		g = (g - d) * 10;
	}
	s1[i] = 0;

	/*
	 * try decimal rounding to eliminate 9s
	 */
	c2 = prec + 1;
	if(chr == 'f')
		c2 += e;
	oerr = errno;
	if(c2 >= NSIGNIF-2) {
		strcpy(s2, s1);
		d = e;
		s1[NSIGNIF-2] = '0';
		s1[NSIGNIF-1] = '0';
		xaddexp(s1+NSIGNIF, e-NSIGNIF+1);
		g = fmtstrtod(s1, nil);
		if(g == f)
			goto found;
		if(xadd(s1, NSIGNIF-3, 1)) {
			e++;
			xaddexp(s1+NSIGNIF, e-NSIGNIF+1);
		}
		g = fmtstrtod(s1, nil);
		if(g == f)
			goto found;
		strcpy(s1, s2);
		e = d;
	}

	/*
	 * convert back so s1 gets exact answer
	 */
	for(d = 0; d < 10; d++) {
		xaddexp(s1+NSIGNIF, e-NSIGNIF+1);
		g = fmtstrtod(s1, nil);
		if(f > g) {
			if(xadd(s1, NSIGNIF-1, 1))
				e--;
			continue;
		}
		if(f < g) {
			if(xsub(s1, NSIGNIF-1, 1))
				e++;
			continue;
		}
		break;
	}

found:
	errno = oerr;

	/*
	 * sign
	 */
	d = 0;
	i = 0;

	/*
	 * round & adjust 'f' digits
	 */
	c2 = prec + 1;
	if(chr == 'f'){
		if(xadd(s1, c2+e, 5))
			e++;
		c2 += e;
		if(c2 < 0){
			c2 = 0;
			e = -prec - 1;
		}
	}else{
		if(xadd(s1, c2, 5))
			e++;
	}
	if(c2 > NSIGNIF){
		c2 = NSIGNIF;
	}

	*decpt = e + 1;

	/*
	 * terminate the converted digits
	 */
	s1[c2] = '\0';
	return &s1[c2];
}