111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/*	$NetBSD: strtod.c,v 1.45.2.1 2005/04/19 13:35:54 tron Exp $	*/
211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/****************************************************************
411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * The author of this software is David M. Gay.
611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Copyright (c) 1991 by AT&T.
811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Permission to use, copy, modify, and distribute this software for any
1011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * purpose without fee is hereby granted, provided that this entire notice
1111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * is included in all copies of any software which is or includes a copy
1211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * or modification of this software and in all copies of the supporting
1311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * documentation for such software.
1411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
1511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
1611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
1711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
1811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
1911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
2011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ***************************************************************/
2111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
2211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* Please send bug reports to
2311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	David M. Gay
2411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	AT&T Bell Laboratories, Room 2C-463
2511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	600 Mountain Avenue
2611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Murray Hill, NJ 07974-2070
2711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	U.S.A.
2811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	dmg@research.att.com or research!dmg
2911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
3011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
3111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* strtod for IEEE-, VAX-, and IBM-arithmetic machines.
3211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
3311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * This strtod returns a nearest machine number to the input decimal
3411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * string (or sets errno to ERANGE).  With IEEE arithmetic, ties are
3511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * broken by the IEEE round-even rule.  Otherwise ties are broken by
3611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * biased rounding (add half and chop).
3711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
3811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Inspired loosely by William D. Clinger's paper "How to Read Floating
3911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
4011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
4111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Modifications:
4211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
4311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	1. We only require IEEE, IBM, or VAX double-precision
4411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *		arithmetic (not IEEE double-extended).
4511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	2. We get by with floating-point arithmetic in a case that
4611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *		Clinger missed -- when we're computing d * 10^n
4711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *		for a small integer d and the integer n is not too
4811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *		much larger than 22 (the maximum integer k for which
4911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *		we can represent 10^k exactly), we may be able to
5011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *		compute (d*10^k) * 10^(e-k) with just one roundoff.
5111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	3. Rather than a bit-at-a-time adjustment of the binary
5211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *		result in the hard case, we use floating-point
5311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *		arithmetic to determine the adjustment to within
5411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *		one bit; only in really hard cases do we need to
5511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *		compute a second residual.
5611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	4. Because of 3., we don't need a large table of powers of 10
5711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *		for ten-to-e (just some small tables, e.g. of 10^k
5811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *		for 0 <= k <= 22).
5911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
6011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
6111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/*
6211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * #define IEEE_LITTLE_ENDIAN for IEEE-arithmetic machines where the least
6311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	significant byte has the lowest address.
6411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * #define IEEE_BIG_ENDIAN for IEEE-arithmetic machines where the most
6511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	significant byte has the lowest address.
6611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * #define Long int on machines with 32-bit ints and 64-bit longs.
6711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * #define Sudden_Underflow for IEEE-format machines without gradual
6811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	underflow (i.e., that flush to zero on underflow).
6911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * #define IBM for IBM mainframe-style floating-point arithmetic.
7011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * #define VAX for VAX-style floating-point arithmetic.
7111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * #define Unsigned_Shifts if >> does treats its left operand as unsigned.
7211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * #define No_leftright to omit left-right logic in fast floating-point
7311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	computation of dtoa.
7411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3.
7511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines
7611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	that use extended-precision instructions to compute rounded
7711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	products and quotients) with IBM.
7811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * #define ROUND_BIASED for IEEE-format with biased rounding.
7911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * #define Inaccurate_Divide for IEEE-format with correctly rounded
8011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	products but inaccurate quotients, e.g., for Intel i860.
8111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * #define Just_16 to store 16 bits per 32-bit Long when doing high-precision
8211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	integer arithmetic.  Whether this speeds things up or slows things
8311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	down depends on the machine and the number being converted.
8411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * #define KR_headers for old-style C function headers.
8511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * #define Bad_float_h if your system lacks a float.h or if it does not
8611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP,
8711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	FLT_RADIX, FLT_ROUNDS, and DBL_MAX.
8811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n)
8911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	if memory is available and otherwise does something you deem
9011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	appropriate.  If MALLOC is undefined, malloc will be invoked
9111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	directly -- and assumed always to succeed.
9211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
9311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
9411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define ANDROID_CHANGES
9511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
9611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef ANDROID_CHANGES
9711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* Needs to be above math.h include below */
9811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "fpmath.h"
9911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
10011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <pthread.h>
10111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define mutex_lock(x) pthread_mutex_lock(x)
10211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define mutex_unlock(x) pthread_mutex_unlock(x)
10311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
10411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
10511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <sys/cdefs.h>
10611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined(LIBC_SCCS) && !defined(lint)
10711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert__RCSID("$NetBSD: strtod.c,v 1.45.2.1 2005/04/19 13:35:54 tron Exp $");
10811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif /* LIBC_SCCS and not lint */
10911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
11011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Unsigned_Shifts
11111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \
11211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    defined(__mips__) || defined(__ns32k__) || defined(__alpha__) || \
11311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    defined(__powerpc__) || defined(__sh__) || defined(__x86_64__) || \
11411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    defined(__hppa__) || \
11511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    defined(__arm__) || defined(__aarch64__)
11611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <endian.h>
11711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if BYTE_ORDER == BIG_ENDIAN
11811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define IEEE_BIG_ENDIAN
11911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
12011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define IEEE_LITTLE_ENDIAN
12111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
12211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
12311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
12411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef __vax__
12511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define VAX
12611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
12711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
12811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined(__hppa__) || defined(__mips__) || defined(__sh__)
12911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define	NAN_WORD0	0x7ff40000
13011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
13111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define	NAN_WORD0	0x7ff80000
13211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
13311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define	NAN_WORD1	0
13411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
13511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Long	int32_t
13611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define ULong	u_int32_t
13711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
13811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef DEBUG
13911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "stdio.h"
14011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
14111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define BugPrintf(x, v) {fprintf(stderr, x, v); exit(1);}
14211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
14311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
14411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef __cplusplus
14511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "malloc.h"
14611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "memory.h"
14711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
14811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef KR_headers
14911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "stdlib.h"
15011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "string.h"
15111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef ANDROID_CHANGES
15211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "locale.h"
15311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif /* ANDROID_CHANGES */
15411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
15511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "malloc.h"
15611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "memory.h"
15711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
15811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
15911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef ANDROID_CHANGES
16011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "extern.h"
16111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "reentrant.h"
16211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif /* ANDROID_CHANGES */
16311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
16411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef MALLOC
16511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef KR_headers
16611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertextern char *MALLOC();
16711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
16811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertextern void *MALLOC(size_t);
16911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
17011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
17111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define MALLOC malloc
17211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
17311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
17411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "ctype.h"
17511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "errno.h"
17611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "float.h"
17711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
17811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef __MATH_H__
17911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "math.h"
18011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
18111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
18211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef __cplusplus
18311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertextern "C" {
18411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
18511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
18611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef CONST
18711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef KR_headers
18811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define CONST /* blank */
18911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
19011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define CONST const
19111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
19211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
19311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
19411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Unsigned_Shifts
19511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Sign_Extend(a,b) if (b < 0) a |= 0xffff0000;
19611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
19711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Sign_Extend(a,b) /*no-op*/
19811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
19911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
20011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + \
20111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    defined(IBM) != 1
20211cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertExactly one of IEEE_LITTLE_ENDIAN IEEE_BIG_ENDIAN, VAX, or
20311cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertIBM should be defined.
20411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
20511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
20611cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttypedef union {
20711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	double d;
20811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	ULong ul[2];
20911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} _double;
21011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define value(x) ((x).d)
21111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef IEEE_LITTLE_ENDIAN
21211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define word0(x) ((x).ul[1])
21311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define word1(x) ((x).ul[0])
21411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
21511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define word0(x) ((x).ul[0])
21611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define word1(x) ((x).ul[1])
21711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
21811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
21911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* The following definition of Storeinc is appropriate for MIPS processors.
22011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * An alternative that might be better on some machines is
22111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
22211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
22311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) + defined(__arm__)
22411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Storeinc(a,b,c) \
22511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    (((u_short *)(void *)a)[1] = \
22611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(u_short)b, ((u_short *)(void *)a)[0] = (u_short)c, a++)
22711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
22811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Storeinc(a,b,c) \
22911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    (((u_short *)(void *)a)[0] = \
23011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(u_short)b, ((u_short *)(void *)a)[1] = (u_short)c, a++)
23111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
23211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
23311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* #define P DBL_MANT_DIG */
23411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* Ten_pmax = floor(P*log(2)/log(5)) */
23511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
23611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
23711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
23811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
23911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN)
24011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Exp_shift  20
24111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Exp_shift1 20
24211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Exp_msk1    0x100000
24311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Exp_msk11   0x100000
24411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Exp_mask  0x7ff00000
24511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define P 53
24611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Bias 1023
24711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define IEEE_Arith
24811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Emin (-1022)
24911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Exp_1  0x3ff00000
25011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Exp_11 0x3ff00000
25111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Ebits 11
25211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Frac_mask  0xfffff
25311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Frac_mask1 0xfffff
25411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Ten_pmax 22
25511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Bletch 0x10
25611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Bndry_mask  0xfffff
25711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Bndry_mask1 0xfffff
25811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define LSB 1
25911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Sign_bit 0x80000000
26011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Log2P 1
26111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Tiny0 0
26211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Tiny1 1
26311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Quick_max 14
26411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Int_max 14
26511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Infinite(x) (word0(x) == 0x7ff00000) /* sufficient test for here */
26611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
26711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#undef  Sudden_Underflow
26811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Sudden_Underflow
26911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef IBM
27011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Exp_shift  24
27111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Exp_shift1 24
27211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Exp_msk1   0x1000000
27311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Exp_msk11  0x1000000
27411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Exp_mask  0x7f000000
27511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define P 14
27611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Bias 65
27711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Exp_1  0x41000000
27811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Exp_11 0x41000000
27911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Ebits 8	/* exponent has 7 bits, but 8 is the right value in b2d */
28011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Frac_mask  0xffffff
28111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Frac_mask1 0xffffff
28211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Bletch 4
28311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Ten_pmax 22
28411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Bndry_mask  0xefffff
28511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Bndry_mask1 0xffffff
28611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define LSB 1
28711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Sign_bit 0x80000000
28811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Log2P 4
28911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Tiny0 0x100000
29011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Tiny1 0
29111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Quick_max 14
29211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Int_max 15
29311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else /* VAX */
29411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Exp_shift  23
29511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Exp_shift1 7
29611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Exp_msk1    0x80
29711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Exp_msk11   0x800000
29811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Exp_mask  0x7f80
29911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define P 56
30011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Bias 129
30111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Exp_1  0x40800000
30211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Exp_11 0x4080
30311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Ebits 8
30411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Frac_mask  0x7fffff
30511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Frac_mask1 0xffff007f
30611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Ten_pmax 24
30711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Bletch 2
30811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Bndry_mask  0xffff007f
30911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Bndry_mask1 0xffff007f
31011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define LSB 0x10000
31111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Sign_bit 0x8000
31211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Log2P 1
31311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Tiny0 0x80
31411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Tiny1 0
31511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Quick_max 15
31611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Int_max 15
31711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
31811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
31911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
32011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef IEEE_Arith
32111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define ROUND_BIASED
32211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
32311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
32411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef RND_PRODQUOT
32511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define rounded_product(a,b) a = rnd_prod(a, b)
32611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define rounded_quotient(a,b) a = rnd_quot(a, b)
32711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef KR_headers
32811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertextern double rnd_prod(), rnd_quot();
32911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
33011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertextern double rnd_prod(double, double), rnd_quot(double, double);
33111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
33211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
33311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define rounded_product(a,b) a *= b
33411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define rounded_quotient(a,b) a /= b
33511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
33611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
33711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
33811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Big1 0xffffffff
33911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
34011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef Just_16
34111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* When Pack_32 is not defined, we store 16 bits per 32-bit Long.
34211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * This makes some inner loops simpler and sometimes saves work
34311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * during multiplications, but it often seems to make things slightly
34411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * slower.  Hence the default is now to store 32 bits per Long.
34511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
34611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef Pack_32
34711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Pack_32
34811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
34911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
35011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
35111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Kmax 15
35211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
35311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Pack_32
35411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define ULbits 32
35511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define kshift 5
35611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define kmask 31
35711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define ALL_ON 0xffffffff
35811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
35911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define ULbits 16
36011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define kshift 4
36111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define kmask 15
36211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define ALL_ON 0xffff
36311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
36411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
36511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Kmax 15
36611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
36711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert enum {	/* return values from strtodg */
36811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	STRTOG_Zero	= 0,
36911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	STRTOG_Normal	= 1,
37011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	STRTOG_Denormal	= 2,
37111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	STRTOG_Infinite	= 3,
37211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	STRTOG_NaN	= 4,
37311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	STRTOG_NaNbits	= 5,
37411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	STRTOG_NoNumber	= 6,
37511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	STRTOG_Retmask	= 7,
37611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
37711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	/* The following may be or-ed into one of the above values. */
37811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
37911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	STRTOG_Neg	= 0x08, /* does not affect STRTOG_Inexlo or STRTOG_Inexhi */
38011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	STRTOG_Inexlo	= 0x10,	/* returned result rounded toward zero */
38111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	STRTOG_Inexhi	= 0x20, /* returned result rounded away from zero */
38211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	STRTOG_Inexact	= 0x30,
38311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	STRTOG_Underflow= 0x40,
38411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	STRTOG_Overflow	= 0x80
38511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	};
38611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
38711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef struct
38811cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertFPI {
38911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int nbits;
39011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int emin;
39111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int emax;
39211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int rounding;
39311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int sudden_underflow;
39411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	} FPI;
39511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
39611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertenum {	/* FPI.rounding values: same as FLT_ROUNDS */
39711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	FPI_Round_zero = 0,
39811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	FPI_Round_near = 1,
39911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	FPI_Round_up = 2,
40011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	FPI_Round_down = 3
40111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	};
40211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
40311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#undef SI
40411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Sudden_Underflow
40511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define SI 1
40611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
40711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define SI 0
40811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
40911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
41011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef __cplusplus
41111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertextern "C" double strtod(const char *s00, char **se);
41211cd02dfb91661c65134cac258cf5924270e9d2Dan Albertextern "C" char *__dtoa(double d, int mode, int ndigits,
41311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			int *decpt, int *sign, char **rve);
41411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
41511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
41611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct
41711cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertBigint {
41811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	struct Bigint *next;
41911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int k, maxwds, sign, wds;
42011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	ULong x[1];
42111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
42211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
42311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef struct Bigint Bigint;
42411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
42511cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertCONST unsigned char hexdig[256] = {
42611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
42711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
42811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
42911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0, 0, 0, 0, 0, 0,
43011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	0, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0, 0, 0, 0, 0, 0, 0, 0, 0,
43111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
43211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	0, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0, 0, 0, 0, 0, 0, 0, 0, 0,
43311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
43411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
43511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
43611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
43711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
43811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
43911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
44011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
44111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
44211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
44311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
44411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic int
44511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertgethex(CONST char **, CONST FPI *, Long *, Bigint **, int, locale_t);
44611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
44711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
44811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static Bigint *freelist[Kmax+1];
44911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
45011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef ANDROID_CHANGES
45111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static pthread_mutex_t freelist_mutex = PTHREAD_MUTEX_INITIALIZER;
45211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
45311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef _REENTRANT
45411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static mutex_t freelist_mutex = MUTEX_INITIALIZER;
45511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
45611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
45711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
45811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* Special value used to indicate an invalid Bigint value,
45911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * e.g. when a memory allocation fails. The idea is that we
46011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * want to avoid introducing NULL checks everytime a bigint
46111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * computation is performed. Also the NULL value can also be
46211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * already used to indicate "value not initialized yet" and
46311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * returning NULL might alter the execution code path in
46411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * case of OOM.
46511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
46611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define  BIGINT_INVALID   ((Bigint *)&bigint_invalid_value)
46711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
46811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic const Bigint bigint_invalid_value;
46911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
47011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
47111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic void
47211cd02dfb91661c65134cac258cf5924270e9d2Dan Albertcopybits(ULong *c, int n, Bigint *b)
47311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
47411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	ULong *ce, *x, *xe;
47511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Pack_16
47611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int nw, nw1;
47711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
47811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
47911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	ce = c + ((n-1) >> kshift) + 1;
48011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	x = b->x;
48111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Pack_32
48211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	xe = x + b->wds;
48311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	while(x < xe)
48411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*c++ = *x++;
48511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
48611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	nw = b->wds;
48711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	nw1 = nw & 1;
48811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	for(xe = x + (nw - nw1); x < xe; x += 2)
48911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		Storeinc(c, x[1], x[0]);
49011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (nw1)
49111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*c++ = *x;
49211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
49311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	while(c < ce)
49411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*c++ = 0;
49511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
49611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
49711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ULong
49811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertany_on(Bigint *b, int k)
49911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
50011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int n, nwds;
50111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	ULong *x, *x0, x1, x2;
50211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
50311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	x = b->x;
50411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	nwds = b->wds;
50511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	n = k >> kshift;
50611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (n > nwds)
50711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		n = nwds;
50811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	else if (n < nwds && (k &= kmask)) {
50911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		x1 = x2 = x[n];
51011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		x1 >>= k;
51111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		x1 <<= k;
51211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (x1 != x2)
51311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			return 1;
51411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
51511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	x0 = x;
51611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	x += n;
51711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	while(x > x0)
51811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (*--x)
51911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			return 1;
52011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return 0;
52111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
52211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
52311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void
52411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertrshift(Bigint *b, int k)
52511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
52611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	ULong *x, *x1, *xe, y;
52711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int n;
52811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
52911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	x = x1 = b->x;
53011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	n = k >> kshift;
53111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (n < b->wds) {
53211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		xe = x + b->wds;
53311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		x += n;
53411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (k &= kmask) {
53511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			n = ULbits - k;
53611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			y = *x++ >> k;
53711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			while(x < xe) {
53811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				*x1++ = (y | (*x << n)) & ALL_ON;
53911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				y = *x++ >> k;
54011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				}
54111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if ((*x1 = y) !=0)
54211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				x1++;
54311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
54411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		else
54511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			while(x < xe)
54611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				*x1++ = *x++;
54711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
54811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if ((b->wds = x1 - b->x) == 0)
54911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		b->x[0] = 0;
55011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
55111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
55211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
55311cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttypedef union { double d; ULong L[2]; } U;
55411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
55511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic void
55611cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertULtod(ULong *L, ULong *bits, Long exp, int k)
55711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
55811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  define _0 1
55911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  define _1 0
56011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
56111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	switch(k & STRTOG_Retmask) {
56211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  case STRTOG_NoNumber:
56311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  case STRTOG_Zero:
56411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		L[0] = L[1] = 0;
56511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		break;
56611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
56711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  case STRTOG_Denormal:
56811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		L[_1] = bits[0];
56911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		L[_0] = bits[1];
57011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		break;
57111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
57211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  case STRTOG_Normal:
57311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  case STRTOG_NaNbits:
57411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		L[_1] = bits[0];
57511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		L[_0] = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20);
57611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		break;
57711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
57811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  case STRTOG_Infinite:
57911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		L[_0] = 0x7ff00000;
58011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		L[_1] = 0;
58111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		break;
58211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
58311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define d_QNAN0 0x7ff80000
58411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define d_QNAN1 0x0
58511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  case STRTOG_NaN:
58611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		L[0] = d_QNAN0;
58711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		L[1] = d_QNAN1;
58811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  }
58911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (k & STRTOG_Neg)
59011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		L[_0] |= 0x80000000L;
59111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
59211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
59311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
59411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
59511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* Return BIGINT_INVALID on allocation failure.
59611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
59711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Most of the code here depends on the fact that this function
59811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * never returns NULL.
59911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
60011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static Bigint *
60111cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertBalloc
60211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef KR_headers
60311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(k) int k;
60411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
60511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(int k)
60611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
60711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
60811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int x;
60911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Bigint *rv;
61011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
61111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	mutex_lock(&freelist_mutex);
61211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
61311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if ((rv = freelist[k]) != NULL) {
61411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		freelist[k] = rv->next;
61511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
61611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	else {
61711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		x = 1 << k;
61811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(Long));
61911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (rv == NULL) {
62011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		        rv = BIGINT_INVALID;
62111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			goto EXIT;
62211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
62311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		rv->k = k;
62411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		rv->maxwds = x;
62511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
62611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	rv->sign = rv->wds = 0;
62711cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertEXIT:
62811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	mutex_unlock(&freelist_mutex);
62911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
63011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return rv;
63111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
63211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
63311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static void
63411cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertBfree
63511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef KR_headers
63611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(v) Bigint *v;
63711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
63811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(Bigint *v)
63911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
64011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
64111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (v && v != BIGINT_INVALID) {
64211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		mutex_lock(&freelist_mutex);
64311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
64411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		v->next = freelist[v->k];
64511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		freelist[v->k] = v;
64611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
64711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		mutex_unlock(&freelist_mutex);
64811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
64911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
65011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
65111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Bcopy_valid(x,y) memcpy(&(x)->sign, &(y)->sign, \
65211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    (y)->wds*sizeof(Long) + 2*sizeof(int))
65311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
65411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define Bcopy(x,y)  Bcopy_ptr(&(x),(y))
65511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
65611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static void
65711cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertBcopy_ptr(Bigint **px, Bigint *y)
65811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
65911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (*px == BIGINT_INVALID)
66011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		return; /* no space to store copy */
66111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (y == BIGINT_INVALID) {
66211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		Bfree(*px); /* invalid input */
66311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*px = BIGINT_INVALID;
66411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	} else {
66511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		Bcopy_valid(*px,y);
66611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
66711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
66811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
66911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static Bigint *
67011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertmultadd
67111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef KR_headers
67211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(b, m, a) Bigint *b; int m, a;
67311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
67411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(Bigint *b, int m, int a)	/* multiply by m and add a */
67511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
67611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
67711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int i, wds;
67811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	ULong *x, y;
67911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Pack_32
68011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	ULong xi, z;
68111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
68211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Bigint *b1;
68311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
68411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (b == BIGINT_INVALID)
68511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		return b;
68611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
68711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	wds = b->wds;
68811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	x = b->x;
68911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	i = 0;
69011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	do {
69111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Pack_32
69211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		xi = *x;
69311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		y = (xi & 0xffff) * m + a;
69411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		z = (xi >> 16) * m + (y >> 16);
69511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		a = (int)(z >> 16);
69611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*x++ = (z << 16) + (y & 0xffff);
69711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
69811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		y = *x * m + a;
69911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		a = (int)(y >> 16);
70011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*x++ = y & 0xffff;
70111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
70211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
70311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	while(++i < wds);
70411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (a) {
70511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (wds >= b->maxwds) {
70611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			b1 = Balloc(b->k+1);
70711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (b1 == BIGINT_INVALID) {
70811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				Bfree(b);
70911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				return b1;
71011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
71111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			Bcopy_valid(b1, b);
71211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			Bfree(b);
71311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			b = b1;
71411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
71511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		b->x[wds++] = a;
71611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		b->wds = wds;
71711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
71811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return b;
71911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
72011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
72111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert Bigint *
72211cd02dfb91661c65134cac258cf5924270e9d2Dan Albertincrement(Bigint *b)
72311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
72411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	ULong *x, *xe;
72511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Bigint *b1;
72611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Pack_16
72711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	ULong carry = 1, y;
72811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
72911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
73011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	x = b->x;
73111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	xe = x + b->wds;
73211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Pack_32
73311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	do {
73411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (*x < (ULong)0xffffffffL) {
73511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			++*x;
73611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			return b;
73711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
73811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*x++ = 0;
73911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		} while(x < xe);
74011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
74111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	do {
74211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		y = *x + carry;
74311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		carry = y >> 16;
74411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*x++ = y & 0xffff;
74511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (!carry)
74611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			return b;
74711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		} while(x < xe);
74811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (carry)
74911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
75011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	{
75111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (b->wds >= b->maxwds) {
75211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			b1 = Balloc(b->k+1);
75311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			Bcopy(b1,b);
75411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			Bfree(b);
75511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			b = b1;
75611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
75711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		b->x[b->wds++] = 1;
75811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
75911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return b;
76011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
76111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
76211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
76311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static Bigint *
76411cd02dfb91661c65134cac258cf5924270e9d2Dan Alberts2b
76511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef KR_headers
76611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9;
76711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
76811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(CONST char *s, int nd0, int nd, ULong y9)
76911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
77011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
77111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Bigint *b;
77211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int i, k;
77311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Long x, y;
77411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
77511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	x = (nd + 8) / 9;
77611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	for(k = 0, y = 1; x > y; y <<= 1, k++) ;
77711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Pack_32
77811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	b = Balloc(k);
77911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (b == BIGINT_INVALID)
78011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		return b;
78111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	b->x[0] = y9;
78211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	b->wds = 1;
78311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
78411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	b = Balloc(k+1);
78511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (b == BIGINT_INVALID)
78611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		return b;
78711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
78811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	b->x[0] = y9 & 0xffff;
78911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
79011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
79111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
79211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	i = 9;
79311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (9 < nd0) {
79411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		s += 9;
79511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		do b = multadd(b, 10, *s++ - '0');
79611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			while(++i < nd0);
79711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		s++;
79811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
79911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	else
80011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		s += 10;
80111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	for(; i < nd; i++)
80211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		b = multadd(b, 10, *s++ - '0');
80311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return b;
80411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
80511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
80611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static int
80711cd02dfb91661c65134cac258cf5924270e9d2Dan Alberthi0bits
80811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef KR_headers
80911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(x) ULong x;
81011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
81111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(ULong x)
81211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
81311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
81411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int k = 0;
81511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
81611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (!(x & 0xffff0000)) {
81711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		k = 16;
81811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		x <<= 16;
81911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
82011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (!(x & 0xff000000)) {
82111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		k += 8;
82211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		x <<= 8;
82311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
82411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (!(x & 0xf0000000)) {
82511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		k += 4;
82611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		x <<= 4;
82711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
82811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (!(x & 0xc0000000)) {
82911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		k += 2;
83011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		x <<= 2;
83111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
83211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (!(x & 0x80000000)) {
83311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		k++;
83411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (!(x & 0x40000000))
83511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			return 32;
83611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
83711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return k;
83811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
83911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
84011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static int
84111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertlo0bits
84211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef KR_headers
84311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(y) ULong *y;
84411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
84511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(ULong *y)
84611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
84711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
84811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int k;
84911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	ULong x = *y;
85011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
85111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (x & 7) {
85211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (x & 1)
85311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			return 0;
85411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (x & 2) {
85511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			*y = x >> 1;
85611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			return 1;
85711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
85811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*y = x >> 2;
85911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		return 2;
86011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
86111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	k = 0;
86211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (!(x & 0xffff)) {
86311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		k = 16;
86411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		x >>= 16;
86511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
86611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (!(x & 0xff)) {
86711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		k += 8;
86811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		x >>= 8;
86911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
87011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (!(x & 0xf)) {
87111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		k += 4;
87211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		x >>= 4;
87311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
87411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (!(x & 0x3)) {
87511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		k += 2;
87611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		x >>= 2;
87711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
87811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (!(x & 1)) {
87911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		k++;
88011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		x >>= 1;
88111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (!x & 1)
88211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			return 32;
88311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
88411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	*y = x;
88511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return k;
88611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
88711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
88811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static Bigint *
88911cd02dfb91661c65134cac258cf5924270e9d2Dan Alberti2b
89011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef KR_headers
89111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(i) int i;
89211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
89311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(int i)
89411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
89511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
89611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Bigint *b;
89711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
89811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	b = Balloc(1);
89911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (b != BIGINT_INVALID) {
90011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		b->x[0] = i;
90111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		b->wds = 1;
90211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
90311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return b;
90411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
90511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
90611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static Bigint *
90711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertmult
90811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef KR_headers
90911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(a, b) Bigint *a, *b;
91011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
91111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(Bigint *a, Bigint *b)
91211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
91311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
91411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Bigint *c;
91511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int k, wa, wb, wc;
91611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	ULong carry, y, z;
91711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
91811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Pack_32
91911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	ULong z2;
92011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
92111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
92211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (a == BIGINT_INVALID || b == BIGINT_INVALID)
92311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		return BIGINT_INVALID;
92411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
92511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (a->wds < b->wds) {
92611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		c = a;
92711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		a = b;
92811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		b = c;
92911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
93011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	k = a->k;
93111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	wa = a->wds;
93211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	wb = b->wds;
93311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	wc = wa + wb;
93411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (wc > a->maxwds)
93511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		k++;
93611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	c = Balloc(k);
93711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (c == BIGINT_INVALID)
93811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		return c;
93911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	for(x = c->x, xa = x + wc; x < xa; x++)
94011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*x = 0;
94111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	xa = a->x;
94211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	xae = xa + wa;
94311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	xb = b->x;
94411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	xbe = xb + wb;
94511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	xc0 = c->x;
94611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Pack_32
94711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	for(; xb < xbe; xb++, xc0++) {
94811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if ((y = *xb & 0xffff) != 0) {
94911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			x = xa;
95011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			xc = xc0;
95111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			carry = 0;
95211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			do {
95311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
95411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				carry = z >> 16;
95511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
95611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				carry = z2 >> 16;
95711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				Storeinc(xc, z2, z);
95811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
95911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			while(x < xae);
96011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			*xc = carry;
96111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
96211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if ((y = *xb >> 16) != 0) {
96311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			x = xa;
96411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			xc = xc0;
96511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			carry = 0;
96611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			z2 = *xc;
96711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			do {
96811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				z = (*x & 0xffff) * y + (*xc >> 16) + carry;
96911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				carry = z >> 16;
97011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				Storeinc(xc, z, z2);
97111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
97211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				carry = z2 >> 16;
97311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
97411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			while(x < xae);
97511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			*xc = z2;
97611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
97711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
97811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
97911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	for(; xb < xbe; xc0++) {
98011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (y = *xb++) {
98111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			x = xa;
98211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			xc = xc0;
98311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			carry = 0;
98411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			do {
98511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				z = *x++ * y + *xc + carry;
98611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				carry = z >> 16;
98711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				*xc++ = z & 0xffff;
98811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
98911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			while(x < xae);
99011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			*xc = carry;
99111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
99211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
99311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
99411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
99511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	c->wds = wc;
99611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return c;
99711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
99811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
99911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static Bigint *p5s;
100011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static pthread_mutex_t p5s_mutex = PTHREAD_MUTEX_INITIALIZER;
100111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
100211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static Bigint *
100311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertpow5mult
100411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef KR_headers
100511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(b, k) Bigint *b; int k;
100611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
100711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(Bigint *b, int k)
100811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
100911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
101011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Bigint *b1, *p5, *p51;
101111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int i;
101211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	static const int p05[3] = { 5, 25, 125 };
101311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
101411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (b == BIGINT_INVALID)
101511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		return b;
101611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
101711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if ((i = k & 3) != 0)
101811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		b = multadd(b, p05[i-1], 0);
101911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
102011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (!(k = (unsigned int) k >> 2))
102111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		return b;
102211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	mutex_lock(&p5s_mutex);
102311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (!(p5 = p5s)) {
102411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		/* first time */
102511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		p5 = i2b(625);
102611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (p5 == BIGINT_INVALID) {
102711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			Bfree(b);
102811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			mutex_unlock(&p5s_mutex);
102911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			return p5;
103011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
103111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		p5s = p5;
103211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		p5->next = 0;
103311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
103411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	for(;;) {
103511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (k & 1) {
103611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			b1 = mult(b, p5);
103711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			Bfree(b);
103811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			b = b1;
103911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
104011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (!(k = (unsigned int) k >> 1))
104111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			break;
104211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (!(p51 = p5->next)) {
104311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			p51 = mult(p5,p5);
104411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (p51 == BIGINT_INVALID) {
104511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				Bfree(b);
104611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				mutex_unlock(&p5s_mutex);
104711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				return p51;
104811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
104911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			p5->next = p51;
105011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			p51->next = 0;
105111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
105211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		p5 = p51;
105311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
105411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	mutex_unlock(&p5s_mutex);
105511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return b;
105611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
105711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
105811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static Bigint *
105911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertlshift
106011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef KR_headers
106111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(b, k) Bigint *b; int k;
106211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
106311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(Bigint *b, int k)
106411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
106511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
106611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int i, k1, n, n1;
106711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Bigint *b1;
106811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	ULong *x, *x1, *xe, z;
106911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
107011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (b == BIGINT_INVALID)
107111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		return b;
107211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
107311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Pack_32
107411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	n = (unsigned int)k >> 5;
107511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
107611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	n = (unsigned int)k >> 4;
107711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
107811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	k1 = b->k;
107911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	n1 = n + b->wds + 1;
108011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	for(i = b->maxwds; n1 > i; i <<= 1)
108111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		k1++;
108211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	b1 = Balloc(k1);
108311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (b1 == BIGINT_INVALID) {
108411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		Bfree(b);
108511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		return b1;
108611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
108711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	x1 = b1->x;
108811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	for(i = 0; i < n; i++)
108911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*x1++ = 0;
109011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	x = b->x;
109111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	xe = x + b->wds;
109211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Pack_32
109311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (k &= 0x1f) {
109411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		k1 = 32 - k;
109511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		z = 0;
109611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		do {
109711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			*x1++ = *x << k | z;
109811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			z = *x++ >> k1;
109911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
110011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		while(x < xe);
110111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if ((*x1 = z) != 0)
110211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			++n1;
110311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
110411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
110511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (k &= 0xf) {
110611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		k1 = 16 - k;
110711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		z = 0;
110811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		do {
110911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			*x1++ = *x << k  & 0xffff | z;
111011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			z = *x++ >> k1;
111111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
111211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		while(x < xe);
111311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (*x1 = z)
111411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			++n1;
111511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
111611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
111711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	else do
111811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*x1++ = *x++;
111911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		while(x < xe);
112011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	b1->wds = n1 - 1;
112111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Bfree(b);
112211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return b1;
112311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
112411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
112511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static int
112611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertcmp
112711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef KR_headers
112811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(a, b) Bigint *a, *b;
112911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
113011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(Bigint *a, Bigint *b)
113111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
113211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
113311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	ULong *xa, *xa0, *xb, *xb0;
113411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int i, j;
113511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
113611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (a == BIGINT_INVALID || b == BIGINT_INVALID)
113711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef DEBUG
113811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		Bug("cmp called with a or b invalid");
113911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
114011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		return 0; /* equal - the best we can do right now */
114111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
114211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
114311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	i = a->wds;
114411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	j = b->wds;
114511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef DEBUG
114611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (i > 1 && !a->x[i-1])
114711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		Bug("cmp called with a->x[a->wds-1] == 0");
114811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (j > 1 && !b->x[j-1])
114911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		Bug("cmp called with b->x[b->wds-1] == 0");
115011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
115111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (i -= j)
115211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		return i;
115311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	xa0 = a->x;
115411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	xa = xa0 + j;
115511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	xb0 = b->x;
115611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	xb = xb0 + j;
115711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	for(;;) {
115811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (*--xa != *--xb)
115911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			return *xa < *xb ? -1 : 1;
116011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (xa <= xa0)
116111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			break;
116211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
116311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return 0;
116411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
116511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
116611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static Bigint *
116711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertdiff
116811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef KR_headers
116911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(a, b) Bigint *a, *b;
117011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
117111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(Bigint *a, Bigint *b)
117211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
117311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
117411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Bigint *c;
117511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int i, wa, wb;
117611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Long borrow, y;	/* We need signed shifts here. */
117711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	ULong *xa, *xae, *xb, *xbe, *xc;
117811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Pack_32
117911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Long z;
118011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
118111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
118211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (a == BIGINT_INVALID || b == BIGINT_INVALID)
118311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		return BIGINT_INVALID;
118411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
118511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	i = cmp(a,b);
118611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (!i) {
118711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		c = Balloc(0);
118811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (c != BIGINT_INVALID) {
118911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			c->wds = 1;
119011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			c->x[0] = 0;
119111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
119211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		return c;
119311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
119411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (i < 0) {
119511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		c = a;
119611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		a = b;
119711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		b = c;
119811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		i = 1;
119911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
120011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	else
120111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		i = 0;
120211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	c = Balloc(a->k);
120311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (c == BIGINT_INVALID)
120411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		return c;
120511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	c->sign = i;
120611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	wa = a->wds;
120711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	xa = a->x;
120811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	xae = xa + wa;
120911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	wb = b->wds;
121011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	xb = b->x;
121111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	xbe = xb + wb;
121211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	xc = c->x;
121311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	borrow = 0;
121411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Pack_32
121511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	do {
121611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		y = (*xa & 0xffff) - (*xb & 0xffff) + borrow;
121711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		borrow = (ULong)y >> 16;
121811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		Sign_Extend(borrow, y);
121911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		z = (*xa++ >> 16) - (*xb++ >> 16) + borrow;
122011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		borrow = (ULong)z >> 16;
122111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		Sign_Extend(borrow, z);
122211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		Storeinc(xc, z, y);
122311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
122411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	while(xb < xbe);
122511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	while(xa < xae) {
122611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		y = (*xa & 0xffff) + borrow;
122711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		borrow = (ULong)y >> 16;
122811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		Sign_Extend(borrow, y);
122911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		z = (*xa++ >> 16) + borrow;
123011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		borrow = (ULong)z >> 16;
123111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		Sign_Extend(borrow, z);
123211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		Storeinc(xc, z, y);
123311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
123411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
123511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	do {
123611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		y = *xa++ - *xb++ + borrow;
123711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		borrow = y >> 16;
123811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		Sign_Extend(borrow, y);
123911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*xc++ = y & 0xffff;
124011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
124111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	while(xb < xbe);
124211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	while(xa < xae) {
124311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		y = *xa++ + borrow;
124411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		borrow = y >> 16;
124511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		Sign_Extend(borrow, y);
124611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*xc++ = y & 0xffff;
124711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
124811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
124911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	while(!*--xc)
125011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		wa--;
125111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	c->wds = wa;
125211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return c;
125311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
125411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
125511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static double
125611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertulp
125711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef KR_headers
125811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(_x) double _x;
125911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
126011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(double _x)
126111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
126211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
126311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	_double x;
126411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Long L;
126511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	_double a;
126611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
126711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	value(x) = _x;
126811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
126911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef Sudden_Underflow
127011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (L > 0) {
127111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
127211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef IBM
127311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		L |= Exp_msk1 >> 4;
127411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
127511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		word0(a) = L;
127611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		word1(a) = 0;
127711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef Sudden_Underflow
127811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
127911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	else {
128011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		L = (ULong)-L >> Exp_shift;
128111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (L < Exp_shift) {
128211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			word0(a) = 0x80000 >> L;
128311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			word1(a) = 0;
128411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
128511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		else {
128611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			word0(a) = 0;
128711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			L -= Exp_shift;
128811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			word1(a) = L >= 31 ? 1 : 1 << (31 - L);
128911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
129011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
129111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
129211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return value(a);
129311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
129411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
129511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static double
129611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertb2d
129711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef KR_headers
129811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(a, e) Bigint *a; int *e;
129911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
130011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(Bigint *a, int *e)
130111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
130211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
130311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	ULong *xa, *xa0, w, y, z;
130411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int k;
130511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	_double d;
130611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VAX
130711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	ULong d0, d1;
130811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
130911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define d0 word0(d)
131011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define d1 word1(d)
131111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
131211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
131311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (a == BIGINT_INVALID)
131411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		return NAN;
131511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
131611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	xa0 = a->x;
131711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	xa = xa0 + a->wds;
131811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	y = *--xa;
131911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef DEBUG
132011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (!y) Bug("zero y in b2d");
132111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
132211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	k = hi0bits(y);
132311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	*e = 32 - k;
132411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Pack_32
132511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (k < Ebits) {
132611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		d0 = Exp_1 | y >> (Ebits - k);
132711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		w = xa > xa0 ? *--xa : 0;
132811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		d1 = y << ((32-Ebits) + k) | w >> (Ebits - k);
132911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		goto ret_d;
133011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
133111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	z = xa > xa0 ? *--xa : 0;
133211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (k -= Ebits) {
133311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		d0 = Exp_1 | y << k | z >> (32 - k);
133411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		y = xa > xa0 ? *--xa : 0;
133511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		d1 = z << k | y >> (32 - k);
133611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
133711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	else {
133811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		d0 = Exp_1 | y;
133911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		d1 = z;
134011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
134111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
134211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (k < Ebits + 16) {
134311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		z = xa > xa0 ? *--xa : 0;
134411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
134511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		w = xa > xa0 ? *--xa : 0;
134611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		y = xa > xa0 ? *--xa : 0;
134711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
134811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		goto ret_d;
134911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
135011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	z = xa > xa0 ? *--xa : 0;
135111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	w = xa > xa0 ? *--xa : 0;
135211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	k -= Ebits + 16;
135311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
135411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	y = xa > xa0 ? *--xa : 0;
135511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	d1 = w << k + 16 | y << k;
135611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
135711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ret_d:
135811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VAX
135911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	word0(d) = d0 >> 16 | d0 << 16;
136011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	word1(d) = d1 >> 16 | d1 << 16;
136111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
136211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#undef d0
136311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#undef d1
136411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
136511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return value(d);
136611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
136711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
136811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static Bigint *
136911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertd2b
137011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef KR_headers
137111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(_d, e, bits) double d; int *e, *bits;
137211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
137311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(double _d, int *e, int *bits)
137411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
137511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
137611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Bigint *b;
137711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int de, i, k;
137811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	ULong *x, y, z;
137911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	_double d;
138011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VAX
138111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	ULong d0, d1;
138211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
138311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
138411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	value(d) = _d;
138511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VAX
138611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	d0 = word0(d) >> 16 | word0(d) << 16;
138711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	d1 = word1(d) >> 16 | word1(d) << 16;
138811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
138911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define d0 word0(d)
139011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define d1 word1(d)
139111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
139211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
139311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Pack_32
139411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	b = Balloc(1);
139511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
139611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	b = Balloc(2);
139711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
139811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (b == BIGINT_INVALID)
139911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		return b;
140011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	x = b->x;
140111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
140211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	z = d0 & Frac_mask;
140311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	d0 &= 0x7fffffff;	/* clear sign bit, which we ignore */
140411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Sudden_Underflow
140511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	de = (int)(d0 >> Exp_shift);
140611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef IBM
140711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	z |= Exp_msk11;
140811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
140911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
141011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if ((de = (int)(d0 >> Exp_shift)) != 0)
141111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		z |= Exp_msk1;
141211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
141311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Pack_32
141411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if ((y = d1) != 0) {
141511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if ((k = lo0bits(&y)) != 0) {
141611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			x[0] = y | z << (32 - k);
141711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			z >>= k;
141811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
141911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		else
142011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			x[0] = y;
142111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		i = b->wds = (x[1] = z) ? 2 : 1;
142211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
142311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	else {
142411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef DEBUG
142511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (!z)
142611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			Bug("Zero passed to d2b");
142711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
142811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		k = lo0bits(&z);
142911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		x[0] = z;
143011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		i = b->wds = 1;
143111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		k += 32;
143211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
143311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
143411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (y = d1) {
143511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (k = lo0bits(&y))
143611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (k >= 16) {
143711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				x[0] = y | z << 32 - k & 0xffff;
143811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				x[1] = z >> k - 16 & 0xffff;
143911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				x[2] = z >> k;
144011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				i = 2;
144111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
144211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			else {
144311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				x[0] = y & 0xffff;
144411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				x[1] = y >> 16 | z << 16 - k & 0xffff;
144511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				x[2] = z >> k & 0xffff;
144611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				x[3] = z >> k+16;
144711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				i = 3;
144811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
144911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		else {
145011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			x[0] = y & 0xffff;
145111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			x[1] = y >> 16;
145211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			x[2] = z & 0xffff;
145311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			x[3] = z >> 16;
145411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			i = 3;
145511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
145611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
145711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	else {
145811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef DEBUG
145911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (!z)
146011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			Bug("Zero passed to d2b");
146111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
146211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		k = lo0bits(&z);
146311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (k >= 16) {
146411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			x[0] = z;
146511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			i = 0;
146611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
146711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		else {
146811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			x[0] = z & 0xffff;
146911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			x[1] = z >> 16;
147011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			i = 1;
147111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
147211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		k += 32;
147311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
147411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	while(!x[i])
147511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		--i;
147611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	b->wds = i + 1;
147711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
147811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef Sudden_Underflow
147911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (de) {
148011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
148111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef IBM
148211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*e = (de - Bias - (P-1) << 2) + k;
148311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);
148411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
148511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*e = de - Bias - (P-1) + k;
148611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*bits = P - k;
148711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
148811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef Sudden_Underflow
148911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
149011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	else {
149111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*e = de - Bias - (P-1) + 1 + k;
149211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Pack_32
149311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*bits = 32*i - hi0bits(x[i-1]);
149411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
149511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*bits = (i+2)*16 - hi0bits(x[i]);
149611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
149711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
149811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
149911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return b;
150011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
150111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#undef d0
150211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#undef d1
150311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
150411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static double
150511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertratio
150611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef KR_headers
150711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(a, b) Bigint *a, *b;
150811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
150911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(Bigint *a, Bigint *b)
151011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
151111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
151211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	_double da, db;
151311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int k, ka, kb;
151411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
151511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (a == BIGINT_INVALID || b == BIGINT_INVALID)
151611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		return NAN; /* for lack of better value ? */
151711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
151811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	value(da) = b2d(a, &ka);
151911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	value(db) = b2d(b, &kb);
152011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Pack_32
152111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	k = ka - kb + 32*(a->wds - b->wds);
152211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
152311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	k = ka - kb + 16*(a->wds - b->wds);
152411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
152511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef IBM
152611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (k > 0) {
152711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		word0(da) += (k >> 2)*Exp_msk1;
152811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (k &= 3)
152911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			da *= 1 << k;
153011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
153111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	else {
153211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		k = -k;
153311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		word0(db) += (k >> 2)*Exp_msk1;
153411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (k &= 3)
153511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			db *= 1 << k;
153611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
153711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
153811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (k > 0)
153911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		word0(da) += k*Exp_msk1;
154011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	else {
154111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		k = -k;
154211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		word0(db) += k*Exp_msk1;
154311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
154411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
154511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return value(da) / value(db);
154611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
154711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
154811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic CONST double
154911cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttens[] = {
155011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
155111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
155211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		1e20, 1e21, 1e22
155311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VAX
155411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		, 1e23, 1e24
155511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
155611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
155711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
155811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef IEEE_Arith
155911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic CONST double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
156011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 };
156111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define n_bigtens 5
156211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
156311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef IBM
156411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic CONST double bigtens[] = { 1e16, 1e32, 1e64 };
156511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 };
156611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define n_bigtens 3
156711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
156811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic CONST double bigtens[] = { 1e16, 1e32 };
156911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic CONST double tinytens[] = { 1e-16, 1e-32 };
157011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define n_bigtens 2
157111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
157211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
157311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
157411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert double
157511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstrtod
157611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef KR_headers
157711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(s00, se) CONST char *s00; char **se;
157811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
157911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(CONST char *s00, char **se)
158011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
158111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
158211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
158311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		 e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
158411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	CONST char *s, *s0, *s1;
158511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	double aadj, aadj1, adj;
158611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	_double rv, rv0;
158711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Long L;
158811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	ULong y, z;
158911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Bigint *bb1, *bd0;
159011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Bigint *bb = NULL, *bd = NULL, *bs = NULL, *delta = NULL;/* pacify gcc */
159111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
159211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef ANDROID_CHANGES
159311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	CONST char decimal_point = '.';
159411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else /* ANDROID_CHANGES */
159511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef KR_headers
159611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	CONST char decimal_point = localeconv()->decimal_point[0];
159711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
159811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	CONST char decimal_point = '.';
159911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
160011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
160111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif /* ANDROID_CHANGES */
160211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
160311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	sign = nz0 = nz = 0;
160411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	value(rv) = 0.;
160511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
160611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
160711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	for(s = s00; isspace((unsigned char) *s); s++)
160811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		;
160911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
161011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (*s == '-') {
161111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		sign = 1;
161211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		s++;
161311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	} else if (*s == '+') {
161411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		s++;
161511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
161611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
161711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (*s == '\0') {
161811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		s = s00;
161911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		goto ret;
162011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
162111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
162211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	/* "INF" or "INFINITY" */
162311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (tolower((unsigned char)*s) == 'i' && strncasecmp(s, "inf", 3) == 0) {
162411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (strncasecmp(s + 3, "inity", 5) == 0)
162511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			s += 8;
162611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		else
162711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			s += 3;
162811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
162911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		value(rv) = HUGE_VAL;
163011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		goto ret;
163111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
163211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
163311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef IEEE_Arith
163411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	/* "NAN" or "NAN(n-char-sequence-opt)" */
163511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (tolower((unsigned char)*s) == 'n' && strncasecmp(s, "nan", 3) == 0) {
163611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		/* Build a quiet NaN. */
163711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		word0(rv) = NAN_WORD0;
163811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		word1(rv) = NAN_WORD1;
163911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		s+= 3;
164011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
164111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		/* Don't interpret (n-char-sequence-opt), for now. */
164211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (*s == '(') {
164311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			s0 = s;
164411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			for (s++; *s != ')' && *s != '\0'; s++)
164511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				;
164611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (*s == ')')
164711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				s++;	/* Skip over closing paren ... */
164811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			else
164911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				s = s0;	/* ... otherwise go back. */
165011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
165111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
165211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		goto ret;
165311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
165411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
165511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
165611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (*s == '0') {
165711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef NO_HEX_FP /*{*/
165811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		{
165911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		static CONST FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI };
166011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		Long exp;
166111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		ULong bits[2];
166211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		switch(s[1]) {
166311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		  case 'x':
166411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		  case 'X':
166511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			{
166611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Honor_FLT_ROUNDS
166711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			FPI fpi1 = fpi;
166811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			fpi1.rounding = Rounding;
166911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
167011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define fpi1 fpi
167111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
167211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			switch((i = gethex(&s, &fpi1, &exp, &bb, sign, 0)) & STRTOG_Retmask) {
167311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			  case STRTOG_NoNumber:
167411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				s = s00;
167511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				sign = 0;
167611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			  case STRTOG_Zero:
167711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				break;
167811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			  default:
167911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (bb) {
168011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					copybits(bits, fpi.nbits, bb);
168111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					Bfree(bb);
168211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					}
168311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				ULtod(((U*)&rv)->L, bits, exp, i);
168411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			  }}
168511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			goto ret;
168611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		  }
168711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
168811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif /*}*/
168911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		nz0 = 1;
169011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		while(*++s == '0') ;
169111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (!*s)
169211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			goto ret;
169311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
169411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	s0 = s;
169511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	y = z = 0;
169611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
169711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (nd < 9)
169811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			y = 10*y + c - '0';
169911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		else if (nd < 16)
170011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			z = 10*z + c - '0';
170111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	nd0 = nd;
170211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (c == decimal_point) {
170311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		c = *++s;
170411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (!nd) {
170511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			for(; c == '0'; c = *++s)
170611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				nz++;
170711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (c > '0' && c <= '9') {
170811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				s0 = s;
170911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				nf += nz;
171011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				nz = 0;
171111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				goto have_dig;
171211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				}
171311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			goto dig_done;
171411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
171511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		for(; c >= '0' && c <= '9'; c = *++s) {
171611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert have_dig:
171711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			nz++;
171811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (c -= '0') {
171911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				nf += nz;
172011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				for(i = 1; i < nz; i++)
172111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					if (nd++ < 9)
172211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert						y *= 10;
172311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					else if (nd <= DBL_DIG + 1)
172411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert						z *= 10;
172511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (nd++ < 9)
172611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					y = 10*y + c;
172711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				else if (nd <= DBL_DIG + 1)
172811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					z = 10*z + c;
172911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				nz = 0;
173011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
173111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
173211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
173311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert dig_done:
173411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	e = 0;
173511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (c == 'e' || c == 'E') {
173611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (!nd && !nz && !nz0) {
173711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			s = s00;
173811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			goto ret;
173911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
174011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		s00 = s;
174111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		esign = 0;
174211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		switch(c = *++s) {
174311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			case '-':
174411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				esign = 1;
174511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				/* FALLTHROUGH */
174611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			case '+':
174711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				c = *++s;
174811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
174911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (c >= '0' && c <= '9') {
175011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			while(c == '0')
175111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				c = *++s;
175211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (c > '0' && c <= '9') {
175311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				L = c - '0';
175411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				s1 = s;
175511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				while((c = *++s) >= '0' && c <= '9')
175611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					L = 10*L + c - '0';
175711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (s - s1 > 8 || L > 19999)
175811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					/* Avoid confusion from exponents
175911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					 * so large that e might overflow.
176011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					 */
176111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					e = 19999; /* safe for 16 bit ints */
176211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				else
176311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					e = (int)L;
176411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (esign)
176511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					e = -e;
176611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
176711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			else
176811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				e = 0;
176911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
177011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		else
177111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			s = s00;
177211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
177311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (!nd) {
177411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (!nz && !nz0)
177511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			s = s00;
177611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		goto ret;
177711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
177811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	e1 = e -= nf;
177911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
178011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	/* Now we have nd0 digits, starting at s0, followed by a
178111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	 * decimal point, followed by nd-nd0 digits.  The number we're
178211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	 * after is the integer represented by those digits times
178311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	 * 10**e */
178411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
178511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (!nd0)
178611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		nd0 = nd;
178711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
178811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	value(rv) = y;
178911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (k > 9)
179011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		value(rv) = tens[k - 9] * value(rv) + z;
179111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	bd0 = 0;
179211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (nd <= DBL_DIG
179311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef RND_PRODQUOT
179411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		&& FLT_ROUNDS == 1
179511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
179611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		) {
179711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (!e)
179811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			goto ret;
179911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (e > 0) {
180011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (e <= Ten_pmax) {
180111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VAX
180211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				goto vax_ovfl_check;
180311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
180411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				/* value(rv) = */ rounded_product(value(rv),
180511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				    tens[e]);
180611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				goto ret;
180711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
180811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
180911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			i = DBL_DIG - nd;
181011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (e <= Ten_pmax + i) {
181111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				/* A fancier test would sometimes let us do
181211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				 * this for larger i values.
181311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				 */
181411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				e -= i;
181511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				value(rv) *= tens[i];
181611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VAX
181711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				/* VAX exponent range is so narrow we must
181811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				 * worry about overflow here...
181911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				 */
182011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert vax_ovfl_check:
182111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				word0(rv) -= P*Exp_msk1;
182211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				/* value(rv) = */ rounded_product(value(rv),
182311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				    tens[e]);
182411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if ((word0(rv) & Exp_mask)
182511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				 > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
182611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					goto ovfl;
182711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				word0(rv) += P*Exp_msk1;
182811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
182911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				/* value(rv) = */ rounded_product(value(rv),
183011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				    tens[e]);
183111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
183211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				goto ret;
183311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
183411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
183511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef Inaccurate_Divide
183611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		else if (e >= -Ten_pmax) {
183711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			/* value(rv) = */ rounded_quotient(value(rv),
183811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    tens[-e]);
183911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			goto ret;
184011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
184111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
184211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
184311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	e1 += nd - k;
184411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
184511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	/* Get starting approximation = rv * 10**e1 */
184611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
184711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (e1 > 0) {
184811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if ((i = e1 & 15) != 0)
184911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			value(rv) *= tens[i];
185011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (e1 &= ~15) {
185111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (e1 > DBL_MAX_10_EXP) {
185211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ovfl:
185311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				errno = ERANGE;
185411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				value(rv) = HUGE_VAL;
185511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (bd0)
185611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					goto retfree;
185711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				goto ret;
185811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
185911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if ((e1 = (unsigned int)e1 >> 4) != 0) {
186011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				for(j = 0; e1 > 1; j++,
186111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				    e1 = (unsigned int)e1 >> 1)
186211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					if (e1 & 1)
186311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert						value(rv) *= bigtens[j];
186411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			/* The last multiplication could overflow. */
186511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				word0(rv) -= P*Exp_msk1;
186611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				value(rv) *= bigtens[j];
186711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if ((z = word0(rv) & Exp_mask)
186811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				 > Exp_msk1*(DBL_MAX_EXP+Bias-P))
186911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					goto ovfl;
187011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
187111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					/* set to largest number */
187211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					/* (Can't trust DBL_MAX) */
187311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					word0(rv) = Big0;
187411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					word1(rv) = Big1;
187511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					}
187611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				else
187711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					word0(rv) += P*Exp_msk1;
187811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
187911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
188011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
188111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	else if (e1 < 0) {
188211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		e1 = -e1;
188311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if ((i = e1 & 15) != 0)
188411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			value(rv) /= tens[i];
188511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (e1 &= ~15) {
188611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			e1 = (unsigned int)e1 >> 4;
188711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (e1 >= 1 << n_bigtens)
188811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				goto undfl;
188911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			for(j = 0; e1 > 1; j++,
189011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    e1 = (unsigned int)e1 >> 1)
189111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (e1 & 1)
189211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					value(rv) *= tinytens[j];
189311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			/* The last multiplication could underflow. */
189411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			value(rv0) = value(rv);
189511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			value(rv) *= tinytens[j];
189611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (!value(rv)) {
189711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				value(rv) = 2.*value(rv0);
189811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				value(rv) *= tinytens[j];
189911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (!value(rv)) {
190011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert undfl:
190111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					value(rv) = 0.;
190211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					errno = ERANGE;
190311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					if (bd0)
190411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert						goto retfree;
190511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					goto ret;
190611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				}
190711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				word0(rv) = Tiny0;
190811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				word1(rv) = Tiny1;
190911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				/* The refinement below will clean
191011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				 * this approximation up.
191111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				 */
191211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
191311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
191411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
191511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
191611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	/* Now the hard part -- adjusting rv to the correct value.*/
191711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
191811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	/* Put digits into bd: true value = bd * 10^e */
191911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
192011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	bd0 = s2b(s0, nd0, nd, y);
192111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
192211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	for(;;) {
192311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		bd = Balloc(bd0->k);
192411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		Bcopy(bd, bd0);
192511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		bb = d2b(value(rv), &bbe, &bbbits);	/* rv = bb * 2^bbe */
192611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		bs = i2b(1);
192711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
192811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (e >= 0) {
192911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			bb2 = bb5 = 0;
193011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			bd2 = bd5 = e;
193111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
193211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		else {
193311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			bb2 = bb5 = -e;
193411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			bd2 = bd5 = 0;
193511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
193611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (bbe >= 0)
193711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			bb2 += bbe;
193811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		else
193911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			bd2 -= bbe;
194011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		bs2 = bb2;
194111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Sudden_Underflow
194211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef IBM
194311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
194411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
194511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		j = P + 1 - bbbits;
194611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
194711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
194811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		i = bbe + bbbits - 1;	/* logb(rv) */
194911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (i < Emin)	/* denormal */
195011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			j = bbe + (P-Emin);
195111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		else
195211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			j = P + 1 - bbbits;
195311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
195411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		bb2 += j;
195511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		bd2 += j;
195611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		i = bb2 < bd2 ? bb2 : bd2;
195711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (i > bs2)
195811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			i = bs2;
195911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (i > 0) {
196011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			bb2 -= i;
196111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			bd2 -= i;
196211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			bs2 -= i;
196311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
196411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (bb5 > 0) {
196511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			bs = pow5mult(bs, bb5);
196611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			bb1 = mult(bs, bb);
196711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			Bfree(bb);
196811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			bb = bb1;
196911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
197011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (bb2 > 0)
197111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			bb = lshift(bb, bb2);
197211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (bd5 > 0)
197311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			bd = pow5mult(bd, bd5);
197411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (bd2 > 0)
197511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			bd = lshift(bd, bd2);
197611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (bs2 > 0)
197711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			bs = lshift(bs, bs2);
197811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		delta = diff(bb, bd);
197911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		dsign = delta->sign;
198011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		delta->sign = 0;
198111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		i = cmp(delta, bs);
198211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (i < 0) {
198311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			/* Error is less than half an ulp -- check for
198411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			 * special case of mantissa a power of two.
198511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			 */
198611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (dsign || word1(rv) || word0(rv) & Bndry_mask)
198711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				break;
198811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			delta = lshift(delta,Log2P);
198911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (cmp(delta, bs) > 0)
199011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				goto drop_down;
199111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			break;
199211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
199311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (i == 0) {
199411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			/* exactly half-way between */
199511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (dsign) {
199611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if ((word0(rv) & Bndry_mask1) == Bndry_mask1
199711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				 &&  word1(rv) == 0xffffffff) {
199811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					/*boundary case -- increment exponent*/
199911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					word0(rv) = (word0(rv) & Exp_mask)
200011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert						+ Exp_msk1
200111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef IBM
200211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert						| Exp_msk1 >> 4
200311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
200411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert						;
200511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					word1(rv) = 0;
200611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					break;
200711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				}
200811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
200911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			else if (!(word0(rv) & Bndry_mask) && !word1(rv)) {
201011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert drop_down:
201111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				/* boundary case -- decrement exponent */
201211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Sudden_Underflow
201311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				L = word0(rv) & Exp_mask;
201411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef IBM
201511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (L <  Exp_msk1)
201611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
201711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (L <= Exp_msk1)
201811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
201911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					goto undfl;
202011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				L -= Exp_msk1;
202111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
202211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				L = (word0(rv) & Exp_mask) - Exp_msk1;
202311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
202411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				word0(rv) = L | Bndry_mask1;
202511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				word1(rv) = 0xffffffff;
202611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef IBM
202711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				goto cont;
202811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
202911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				break;
203011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
203111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
203211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef ROUND_BIASED
203311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (!(word1(rv) & LSB))
203411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				break;
203511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
203611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (dsign)
203711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				value(rv) += ulp(value(rv));
203811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef ROUND_BIASED
203911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			else {
204011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				value(rv) -= ulp(value(rv));
204111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef Sudden_Underflow
204211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (!value(rv))
204311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					goto undfl;
204411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
204511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
204611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
204711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			break;
204811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
204911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if ((aadj = ratio(delta, bs)) <= 2.) {
205011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (dsign)
205111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				aadj = aadj1 = 1.;
205211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			else if (word1(rv) || word0(rv) & Bndry_mask) {
205311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef Sudden_Underflow
205411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (word1(rv) == Tiny1 && !word0(rv))
205511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					goto undfl;
205611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
205711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				aadj = 1.;
205811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				aadj1 = -1.;
205911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
206011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			else {
206111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				/* special case -- power of FLT_RADIX to be */
206211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				/* rounded down... */
206311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
206411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (aadj < 2./FLT_RADIX)
206511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					aadj = 1./FLT_RADIX;
206611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				else
206711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					aadj *= 0.5;
206811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				aadj1 = -aadj;
206911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				}
207011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
207111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		else {
207211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			aadj *= 0.5;
207311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			aadj1 = dsign ? aadj : -aadj;
207411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Check_FLT_ROUNDS
207511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			switch(FLT_ROUNDS) {
207611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				case 2: /* towards +infinity */
207711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					aadj1 -= 0.5;
207811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					break;
207911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				case 0: /* towards 0 */
208011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				case 3: /* towards -infinity */
208111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					aadj1 += 0.5;
208211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
208311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
208411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (FLT_ROUNDS == 0)
208511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				aadj1 += 0.5;
208611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
208711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
208811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		y = word0(rv) & Exp_mask;
208911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
209011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		/* Check for overflow */
209111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
209211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
209311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			value(rv0) = value(rv);
209411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			word0(rv) -= P*Exp_msk1;
209511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			adj = aadj1 * ulp(value(rv));
209611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			value(rv) += adj;
209711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if ((word0(rv) & Exp_mask) >=
209811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
209911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (word0(rv0) == Big0 && word1(rv0) == Big1)
210011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					goto ovfl;
210111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				word0(rv) = Big0;
210211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				word1(rv) = Big1;
210311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				goto cont;
210411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
210511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			else
210611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				word0(rv) += P*Exp_msk1;
210711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
210811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		else {
210911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Sudden_Underflow
211011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
211111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				value(rv0) = value(rv);
211211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				word0(rv) += P*Exp_msk1;
211311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				adj = aadj1 * ulp(value(rv));
211411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				value(rv) += adj;
211511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef IBM
211611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if ((word0(rv) & Exp_mask) <  P*Exp_msk1)
211711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
211811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if ((word0(rv) & Exp_mask) <= P*Exp_msk1)
211911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
212011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				{
212111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					if (word0(rv0) == Tiny0
212211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					 && word1(rv0) == Tiny1)
212311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert						goto undfl;
212411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					word0(rv) = Tiny0;
212511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					word1(rv) = Tiny1;
212611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					goto cont;
212711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				}
212811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				else
212911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					word0(rv) -= P*Exp_msk1;
213011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				}
213111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			else {
213211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				adj = aadj1 * ulp(value(rv));
213311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				value(rv) += adj;
213411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
213511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
213611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			/* Compute adj so that the IEEE rounding rules will
213711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			 * correctly round rv + adj in some half-way cases.
213811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			 * If rv * ulp(rv) is denormalized (i.e.,
213911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			 * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
214011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			 * trouble from bits lost to denormalization;
214111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			 * example: 1.2e-307 .
214211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			 */
214311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (y <= (P-1)*Exp_msk1 && aadj >= 1.) {
214411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				aadj1 = (double)(int)(aadj + 0.5);
214511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (!dsign)
214611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					aadj1 = -aadj1;
214711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
214811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			adj = aadj1 * ulp(value(rv));
214911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			value(rv) += adj;
215011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
215111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
215211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		z = word0(rv) & Exp_mask;
215311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (y == z) {
215411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			/* Can we stop now? */
215511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			L = aadj;
215611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			aadj -= L;
215711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			/* The tolerances below are conservative. */
215811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (dsign || word1(rv) || word0(rv) & Bndry_mask) {
215911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (aadj < .4999999 || aadj > .5000001)
216011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					break;
216111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
216211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			else if (aadj < .4999999/FLT_RADIX)
216311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				break;
216411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
216511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert cont:
216611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		Bfree(bb);
216711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		Bfree(bd);
216811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		Bfree(bs);
216911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		Bfree(delta);
217011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
217111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert retfree:
217211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Bfree(bb);
217311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Bfree(bd);
217411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Bfree(bs);
217511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Bfree(bd0);
217611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Bfree(delta);
217711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ret:
217811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (se)
217911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		/* LINTED interface specification */
218011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*se = (char *)s;
218111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return sign ? -value(rv) : value(rv);
218211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
218311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
218411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static int
218511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertquorem
218611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef KR_headers
218711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(b, S) Bigint *b, *S;
218811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
218911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(Bigint *b, Bigint *S)
219011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
219111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
219211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int n;
219311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Long borrow, y;
219411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	ULong carry, q, ys;
219511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	ULong *bx, *bxe, *sx, *sxe;
219611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Pack_32
219711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Long z;
219811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	ULong si, zs;
219911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
220011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
220111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (b == BIGINT_INVALID || S == BIGINT_INVALID)
220211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		return 0;
220311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
220411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	n = S->wds;
220511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef DEBUG
220611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	/*debug*/ if (b->wds > n)
220711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	/*debug*/	Bug("oversize b in quorem");
220811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
220911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (b->wds < n)
221011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		return 0;
221111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	sx = S->x;
221211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	sxe = sx + --n;
221311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	bx = b->x;
221411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	bxe = bx + n;
221511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	q = *bxe / (*sxe + 1);	/* ensure q <= true quotient */
221611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef DEBUG
221711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	/*debug*/ if (q > 9)
221811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	/*debug*/	Bug("oversized quotient in quorem");
221911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
222011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (q) {
222111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		borrow = 0;
222211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		carry = 0;
222311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		do {
222411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Pack_32
222511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			si = *sx++;
222611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			ys = (si & 0xffff) * q + carry;
222711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			zs = (si >> 16) * q + (ys >> 16);
222811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			carry = zs >> 16;
222911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
223011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			borrow = (ULong)y >> 16;
223111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			Sign_Extend(borrow, y);
223211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			z = (*bx >> 16) - (zs & 0xffff) + borrow;
223311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			borrow = (ULong)z >> 16;
223411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			Sign_Extend(borrow, z);
223511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			Storeinc(bx, z, y);
223611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
223711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			ys = *sx++ * q + carry;
223811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			carry = ys >> 16;
223911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			y = *bx - (ys & 0xffff) + borrow;
224011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			borrow = y >> 16;
224111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			Sign_Extend(borrow, y);
224211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			*bx++ = y & 0xffff;
224311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
224411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
224511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		while(sx <= sxe);
224611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (!*bxe) {
224711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			bx = b->x;
224811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			while(--bxe > bx && !*bxe)
224911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				--n;
225011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			b->wds = n;
225111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
225211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
225311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (cmp(b, S) >= 0) {
225411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		q++;
225511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		borrow = 0;
225611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		carry = 0;
225711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		bx = b->x;
225811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		sx = S->x;
225911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		do {
226011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Pack_32
226111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			si = *sx++;
226211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			ys = (si & 0xffff) + carry;
226311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			zs = (si >> 16) + (ys >> 16);
226411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			carry = zs >> 16;
226511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
226611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			borrow = (ULong)y >> 16;
226711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			Sign_Extend(borrow, y);
226811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			z = (*bx >> 16) - (zs & 0xffff) + borrow;
226911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			borrow = (ULong)z >> 16;
227011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			Sign_Extend(borrow, z);
227111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			Storeinc(bx, z, y);
227211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
227311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			ys = *sx++ + carry;
227411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			carry = ys >> 16;
227511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			y = *bx - (ys & 0xffff) + borrow;
227611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			borrow = y >> 16;
227711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			Sign_Extend(borrow, y);
227811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			*bx++ = y & 0xffff;
227911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
228011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
228111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		while(sx <= sxe);
228211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		bx = b->x;
228311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		bxe = bx + n;
228411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (!*bxe) {
228511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			while(--bxe > bx && !*bxe)
228611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				--n;
228711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			b->wds = n;
228811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
228911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
229011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return q;
229111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
229211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
229311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* freedtoa(s) must be used to free values s returned by dtoa
229411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * when MULTIPLE_THREADS is #defined.  It should be used in all cases,
229511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * but for consistency with earlier versions of dtoa, it is optional
229611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * when MULTIPLE_THREADS is not defined.
229711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
229811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
229911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid
230011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef KR_headers
230111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertfreedtoa(s) char *s;
230211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
230311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertfreedtoa(char *s)
230411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
230511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
230611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	free(s);
230711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
230811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
230911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
231011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
231111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
231211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
231311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Inspired by "How to Print Floating-Point Numbers Accurately" by
231411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
231511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
231611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Modifications:
231711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	1. Rather than iterating, we use a simple numeric overestimate
231811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	   to determine k = floor(log10(d)).  We scale relevant
231911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	   quantities using O(log2(k)) rather than O(k) multiplications.
232011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
232111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	   try to generate digits strictly left to right.  Instead, we
232211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	   compute with fewer bits and propagate the carry if necessary
232311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	   when rounding the final digit up.  This is often faster.
232411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	3. Under the assumption that input will be rounded nearest,
232511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	   mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
232611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	   That is, we allow equality in stopping tests when the
232711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	   round-nearest rule will give the same floating-point value
232811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	   as would satisfaction of the stopping test with strict
232911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	   inequality.
233011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	4. We remove common factors of powers of 2 from relevant
233111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	   quantities.
233211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	5. When converting floating-point integers less than 1e16,
233311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	   we use floating-point arithmetic rather than resorting
233411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	   to multiple-precision integers.
233511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	6. When asked to produce fewer than 15 digits, we first try
233611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	   to get by with floating-point arithmetic; we resort to
233711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	   multiple-precision integer arithmetic only if we cannot
233811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	   guarantee that the floating-point calculation has given
233911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	   the correctly rounded result.  For k requested digits and
234011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	   "uniformly" distributed input, the probability is
234111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	   something like 10^(k-15) that we must resort to the Long
234211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *	   calculation.
234311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
234411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
234511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert__LIBC_HIDDEN__  char *
234611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert__dtoa
234711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef KR_headers
234811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(_d, mode, ndigits, decpt, sign, rve)
234911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	double _d; int mode, ndigits, *decpt, *sign; char **rve;
235011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
235111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	(double _d, int mode, int ndigits, int *decpt, int *sign, char **rve)
235211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
235311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
235411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /*	Arguments ndigits, decpt, sign are similar to those
235511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	of ecvt and fcvt; trailing zeros are suppressed from
235611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	the returned string.  If not null, *rve is set to point
235711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	to the end of the return value.  If d is +-Infinity or NaN,
235811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	then *decpt is set to 9999.
235911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
236011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	mode:
236111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		0 ==> shortest string that yields d when read in
236211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			and rounded to nearest.
236311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		1 ==> like 0, but with Steele & White stopping rule;
236411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			e.g. with IEEE P754 arithmetic , mode 0 gives
236511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			1e23 whereas mode 1 gives 9.999999999999999e22.
236611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		2 ==> max(1,ndigits) significant digits.  This gives a
236711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			return value similar to that of ecvt, except
236811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			that trailing zeros are suppressed.
236911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		3 ==> through ndigits past the decimal point.  This
237011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			gives a return value similar to that from fcvt,
237111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			except that trailing zeros are suppressed, and
237211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			ndigits can be negative.
237311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		4-9 should give the same return values as 2-3, i.e.,
237411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			4 <= mode <= 9 ==> same return as mode
237511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			2 + (mode & 1).  These modes are mainly for
237611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			debugging; often they run slower but sometimes
237711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			faster than modes 2-3.
237811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		4,5,8,9 ==> left-to-right digit generation.
237911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		6-9 ==> don't try fast floating-point estimate
238011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			(if applicable).
238111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
238211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		Values of mode other than 0-9 are treated as mode 0.
238311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
238411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		Sufficient space is allocated to the return value
238511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		to hold the suppressed trailing zeros.
238611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	*/
238711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
238811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int bbits, b2, b5, be, dig, i, ieps, ilim0,
238911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		j, jj1, k, k0, k_check, leftright, m2, m5, s2, s5,
239011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		try_quick;
239111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int ilim = 0, ilim1 = 0, spec_case = 0;	/* pacify gcc */
239211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Long L;
239311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef Sudden_Underflow
239411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int denorm;
239511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	ULong x;
239611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
239711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Bigint *b, *b1, *delta, *mhi, *S;
239811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Bigint *mlo = NULL; /* pacify gcc */
239911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	double ds;
240011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	char *s, *s0;
240111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Bigint *result = NULL;
240211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int result_k = 0;
240311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	_double d, d2, eps;
240411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
240511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	value(d) = _d;
240611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
240711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (word0(d) & Sign_bit) {
240811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		/* set sign for everything, including 0's and NaNs */
240911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*sign = 1;
241011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		word0(d) &= ~Sign_bit;	/* clear sign bit */
241111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
241211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	else
241311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*sign = 0;
241411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
241511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined(IEEE_Arith) + defined(VAX)
241611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef IEEE_Arith
241711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if ((word0(d) & Exp_mask) == Exp_mask)
241811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
241911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (word0(d)  == 0x8000)
242011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
242111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	{
242211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		/* Infinity or NaN */
242311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*decpt = 9999;
242411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		s =
242511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef IEEE_Arith
242611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			!word1(d) && !(word0(d) & 0xfffff) ? "Infinity" :
242711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
242811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				"NaN";
242911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		result = Balloc(strlen(s)+1);
243011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (result == BIGINT_INVALID)
243111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			return NULL;
243211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		s0 = (char *)(void *)result;
243311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		strcpy(s0, s);
243411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (rve)
243511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			*rve =
243611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef IEEE_Arith
243711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				s0[3] ? s0 + 8 :
243811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
243911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				s0 + 3;
244011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		return s0;
244111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
244211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
244311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef IBM
244411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	value(d) += 0; /* normalize */
244511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
244611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (!value(d)) {
244711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*decpt = 1;
244811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		result = Balloc(2);
244911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (result == BIGINT_INVALID)
245011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			return NULL;
245111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		s0 = (char *)(void *)result;
245211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		strcpy(s0, "0");
245311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (rve)
245411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			*rve = s0 + 1;
245511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		return s0;
245611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
245711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
245811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	b = d2b(value(d), &be, &bbits);
245911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Sudden_Underflow
246011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
246111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
246211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if ((i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) {
246311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
246411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		value(d2) = value(d);
246511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		word0(d2) &= Frac_mask1;
246611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		word0(d2) |= Exp_11;
246711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef IBM
246811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (j = 11 - hi0bits(word0(d2) & Frac_mask))
246911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			value(d2) /= 1 << j;
247011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
247111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
247211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		/* log(x)	~=~ log(1.5) + (x-1.5)/1.5
247311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		 * log10(x)	 =  log(x) / log(10)
247411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		 *		~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
247511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		 * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
247611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		 *
247711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		 * This suggests computing an approximation k to log10(d) by
247811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		 *
247911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		 * k = (i - Bias)*0.301029995663981
248011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		 *	+ ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
248111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		 *
248211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		 * We want k to be too large rather than too small.
248311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		 * The error in the first-order Taylor series approximation
248411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		 * is in our favor, so we just round up the constant enough
248511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		 * to compensate for any error in the multiplication of
248611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		 * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
248711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		 * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
248811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		 * adding 1e-13 to the constant term more than suffices.
248911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		 * Hence we adjust the constant term to 0.1760912590558.
249011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		 * (We could get a more accurate k by invoking log10,
249111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		 *  but this is probably not worthwhile.)
249211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		 */
249311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
249411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		i -= Bias;
249511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef IBM
249611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		i <<= 2;
249711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		i += j;
249811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
249911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef Sudden_Underflow
250011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		denorm = 0;
250111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
250211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	else {
250311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		/* d is denormalized */
250411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
250511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		i = bbits + be + (Bias + (P-1) - 1);
250611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		x = i > 32  ? word0(d) << (64 - i) | word1(d) >> (i - 32)
250711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    : word1(d) << (32 - i);
250811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		value(d2) = x;
250911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		word0(d2) -= 31*Exp_msk1; /* adjust exponent */
251011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		i -= (Bias + (P-1) - 1) + 1;
251111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		denorm = 1;
251211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
251311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
251411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	ds = (value(d2)-1.5)*0.289529654602168 + 0.1760912590558 +
251511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	    i*0.301029995663981;
251611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	k = (int)ds;
251711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (ds < 0. && ds != k)
251811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		k--;	/* want k = floor(ds) */
251911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	k_check = 1;
252011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (k >= 0 && k <= Ten_pmax) {
252111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (value(d) < tens[k])
252211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			k--;
252311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		k_check = 0;
252411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
252511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	j = bbits - i - 1;
252611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (j >= 0) {
252711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		b2 = 0;
252811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		s2 = j;
252911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
253011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	else {
253111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		b2 = -j;
253211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		s2 = 0;
253311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
253411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (k >= 0) {
253511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		b5 = 0;
253611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		s5 = k;
253711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		s2 += k;
253811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
253911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	else {
254011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		b2 -= k;
254111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		b5 = -k;
254211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		s5 = 0;
254311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
254411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (mode < 0 || mode > 9)
254511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		mode = 0;
254611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	try_quick = 1;
254711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (mode > 5) {
254811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		mode -= 4;
254911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		try_quick = 0;
255011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
255111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	leftright = 1;
255211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	switch(mode) {
255311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		case 0:
255411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		case 1:
255511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			ilim = ilim1 = -1;
255611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			i = 18;
255711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			ndigits = 0;
255811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			break;
255911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		case 2:
256011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			leftright = 0;
256111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			/* FALLTHROUGH */
256211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		case 4:
256311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (ndigits <= 0)
256411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				ndigits = 1;
256511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			ilim = ilim1 = i = ndigits;
256611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			break;
256711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		case 3:
256811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			leftright = 0;
256911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			/* FALLTHROUGH */
257011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		case 5:
257111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			i = ndigits + k + 1;
257211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			ilim = i;
257311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			ilim1 = i - 1;
257411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (i <= 0)
257511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				i = 1;
257611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
257711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	j = sizeof(ULong);
257811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        for(result_k = 0; (int)(sizeof(Bigint) - sizeof(ULong)) + j <= i;
257911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		j <<= 1) result_k++;
258011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        // this is really a ugly hack, the code uses Balloc
258111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        // instead of malloc, but casts the result into a char*
258211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        // it seems the only reason to do that is due to the
258311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        // complicated way the block size need to be computed
258411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        // buuurk....
258511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	result = Balloc(result_k);
258611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (result == BIGINT_INVALID) {
258711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		Bfree(b);
258811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		return NULL;
258911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
259011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	s = s0 = (char *)(void *)result;
259111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
259211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (ilim >= 0 && ilim <= Quick_max && try_quick) {
259311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
259411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		/* Try to get by with floating-point arithmetic. */
259511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
259611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		i = 0;
259711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		value(d2) = value(d);
259811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		k0 = k;
259911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		ilim0 = ilim;
260011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		ieps = 2; /* conservative */
260111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (k > 0) {
260211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			ds = tens[k&0xf];
260311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			j = (unsigned int)k >> 4;
260411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (j & Bletch) {
260511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				/* prevent overflows */
260611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				j &= Bletch - 1;
260711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				value(d) /= bigtens[n_bigtens-1];
260811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				ieps++;
260911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				}
261011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			for(; j; j = (unsigned int)j >> 1, i++)
261111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (j & 1) {
261211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					ieps++;
261311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					ds *= bigtens[i];
261411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					}
261511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			value(d) /= ds;
261611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
261711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		else if ((jj1 = -k) != 0) {
261811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			value(d) *= tens[jj1 & 0xf];
261911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			for(j = (unsigned int)jj1 >> 4; j;
262011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    j = (unsigned int)j >> 1, i++)
262111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (j & 1) {
262211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					ieps++;
262311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					value(d) *= bigtens[i];
262411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				}
262511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
262611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (k_check && value(d) < 1. && ilim > 0) {
262711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (ilim1 <= 0)
262811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				goto fast_failed;
262911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			ilim = ilim1;
263011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			k--;
263111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			value(d) *= 10.;
263211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			ieps++;
263311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
263411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		value(eps) = ieps*value(d) + 7.;
263511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		word0(eps) -= (P-1)*Exp_msk1;
263611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (ilim == 0) {
263711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			S = mhi = 0;
263811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			value(d) -= 5.;
263911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (value(d) > value(eps))
264011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				goto one_digit;
264111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (value(d) < -value(eps))
264211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				goto no_digits;
264311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			goto fast_failed;
264411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
264511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef No_leftright
264611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (leftright) {
264711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			/* Use Steele & White method of only
264811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			 * generating digits needed.
264911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			 */
265011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			value(eps) = 0.5/tens[ilim-1] - value(eps);
265111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			for(i = 0;;) {
265211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				L = value(d);
265311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				value(d) -= L;
265411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				*s++ = '0' + (int)L;
265511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (value(d) < value(eps))
265611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					goto ret1;
265711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (1. - value(d) < value(eps))
265811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					goto bump_up;
265911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (++i >= ilim)
266011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					break;
266111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				value(eps) *= 10.;
266211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				value(d) *= 10.;
266311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				}
266411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
266511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		else {
266611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
266711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			/* Generate ilim digits, then fix them up. */
266811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			value(eps) *= tens[ilim-1];
266911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			for(i = 1;; i++, value(d) *= 10.) {
267011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				L = value(d);
267111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				value(d) -= L;
267211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				*s++ = '0' + (int)L;
267311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (i == ilim) {
267411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					if (value(d) > 0.5 + value(eps))
267511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert						goto bump_up;
267611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					else if (value(d) < 0.5 - value(eps)) {
267711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert						while(*--s == '0');
267811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert						s++;
267911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert						goto ret1;
268011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert						}
268111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					break;
268211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				}
268311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
268411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef No_leftright
268511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
268611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
268711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert fast_failed:
268811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		s = s0;
268911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		value(d) = value(d2);
269011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		k = k0;
269111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		ilim = ilim0;
269211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
269311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
269411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	/* Do we have a "small" integer? */
269511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
269611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (be >= 0 && k <= Int_max) {
269711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		/* Yes. */
269811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		ds = tens[k];
269911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (ndigits < 0 && ilim <= 0) {
270011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			S = mhi = 0;
270111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (ilim < 0 || value(d) <= 5*ds)
270211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				goto no_digits;
270311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			goto one_digit;
270411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
270511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		for(i = 1;; i++) {
270611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			L = value(d) / ds;
270711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			value(d) -= L*ds;
270811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Check_FLT_ROUNDS
270911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			/* If FLT_ROUNDS == 2, L will usually be high by 1 */
271011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (value(d) < 0) {
271111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				L--;
271211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				value(d) += ds;
271311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
271411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
271511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			*s++ = '0' + (int)L;
271611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (i == ilim) {
271711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				value(d) += value(d);
271811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (value(d) > ds || (value(d) == ds && L & 1)) {
271911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bump_up:
272011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					while(*--s == '9')
272111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert						if (s == s0) {
272211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert							k++;
272311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert							*s = '0';
272411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert							break;
272511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert						}
272611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					++*s++;
272711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				}
272811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				break;
272911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
273011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (!(value(d) *= 10.))
273111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				break;
273211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
273311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		goto ret1;
273411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
273511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
273611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	m2 = b2;
273711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	m5 = b5;
273811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	mhi = mlo = 0;
273911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (leftright) {
274011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (mode < 2) {
274111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			i =
274211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef Sudden_Underflow
274311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				denorm ? be + (Bias + (P-1) - 1 + 1) :
274411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
274511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef IBM
274611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
274711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
274811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				1 + P - bbits;
274911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
275011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
275111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		else {
275211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			j = ilim - 1;
275311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (m5 >= j)
275411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				m5 -= j;
275511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			else {
275611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				s5 += j -= m5;
275711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				b5 += j;
275811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				m5 = 0;
275911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
276011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if ((i = ilim) < 0) {
276111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				m2 -= i;
276211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				i = 0;
276311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
276411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
276511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		b2 += i;
276611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		s2 += i;
276711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		mhi = i2b(1);
276811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
276911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (m2 > 0 && s2 > 0) {
277011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		i = m2 < s2 ? m2 : s2;
277111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		b2 -= i;
277211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		m2 -= i;
277311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		s2 -= i;
277411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
277511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (b5 > 0) {
277611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (leftright) {
277711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (m5 > 0) {
277811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				mhi = pow5mult(mhi, m5);
277911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				b1 = mult(mhi, b);
278011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				Bfree(b);
278111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				b = b1;
278211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
278311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if ((j = b5 - m5) != 0)
278411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				b = pow5mult(b, j);
278511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
278611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		else
278711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			b = pow5mult(b, b5);
278811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
278911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	S = i2b(1);
279011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (s5 > 0)
279111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		S = pow5mult(S, s5);
279211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
279311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	/* Check for special case that d is a normalized power of 2. */
279411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
279511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (mode < 2) {
279611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (!word1(d) && !(word0(d) & Bndry_mask)
279711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef Sudden_Underflow
279811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		 && word0(d) & Exp_mask
279911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
280011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				) {
280111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			/* The special case */
280211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			b2 += Log2P;
280311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			s2 += Log2P;
280411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			spec_case = 1;
280511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
280611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		else
280711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			spec_case = 0;
280811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
280911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
281011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	/* Arrange for convenient computation of quotients:
281111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	 * shift left if necessary so divisor has 4 leading 0 bits.
281211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	 *
281311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	 * Perhaps we should just compute leading 28 bits of S once
281411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	 * and for all and pass them and a shift to quorem, so it
281511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	 * can do shifts and ors to compute the numerator for q.
281611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	 */
281711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (S == BIGINT_INVALID) {
281811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		i = 0;
281911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	} else {
282011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef Pack_32
282111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) != 0)
282211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			i = 32 - i;
282311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
282411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf)
282511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			i = 16 - i;
282611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
282711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
282811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
282911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (i > 4) {
283011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		i -= 4;
283111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		b2 += i;
283211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		m2 += i;
283311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		s2 += i;
283411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
283511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	else if (i < 4) {
283611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		i += 28;
283711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		b2 += i;
283811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		m2 += i;
283911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		s2 += i;
284011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
284111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (b2 > 0)
284211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		b = lshift(b, b2);
284311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (s2 > 0)
284411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		S = lshift(S, s2);
284511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (k_check) {
284611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (cmp(b,S) < 0) {
284711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			k--;
284811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			b = multadd(b, 10, 0);	/* we botched the k estimate */
284911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (leftright)
285011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				mhi = multadd(mhi, 10, 0);
285111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			ilim = ilim1;
285211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
285311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
285411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (ilim <= 0 && mode > 2) {
285511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
285611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			/* no digits, fcvt style */
285711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert no_digits:
285811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			k = -1 - ndigits;
285911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			goto ret;
286011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
286111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert one_digit:
286211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*s++ = '1';
286311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		k++;
286411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		goto ret;
286511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
286611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (leftright) {
286711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (m2 > 0)
286811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			mhi = lshift(mhi, m2);
286911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
287011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		/* Compute mlo -- check for special case
287111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		 * that d is a normalized power of 2.
287211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		 */
287311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
287411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		mlo = mhi;
287511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (spec_case) {
287611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			mhi = Balloc(mhi->k);
287711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			Bcopy(mhi, mlo);
287811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			mhi = lshift(mhi, Log2P);
287911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
288011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
288111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		for(i = 1;;i++) {
288211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			dig = quorem(b,S) + '0';
288311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			/* Do we yet have the shortest decimal string
288411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			 * that will round to d?
288511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			 */
288611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			j = cmp(b, mlo);
288711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			delta = diff(S, mhi);
288811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			jj1 = delta->sign ? 1 : cmp(b, delta);
288911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			Bfree(delta);
289011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef ROUND_BIASED
289111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (jj1 == 0 && !mode && !(word1(d) & 1)) {
289211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (dig == '9')
289311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					goto round_9_up;
289411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (j > 0)
289511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					dig++;
289611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				*s++ = dig;
289711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				goto ret;
289811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
289911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
290011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (j < 0 || (j == 0 && !mode
290111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef ROUND_BIASED
290211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert							&& !(word1(d) & 1)
290311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
290411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					)) {
290511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (jj1 > 0) {
290611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					b = lshift(b, 1);
290711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					jj1 = cmp(b, S);
290811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					if ((jj1 > 0 || (jj1 == 0 && dig & 1))
290911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					&& dig++ == '9')
291011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert						goto round_9_up;
291111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					}
291211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				*s++ = dig;
291311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				goto ret;
291411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
291511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (jj1 > 0) {
291611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (dig == '9') { /* possible if i == 1 */
291711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert round_9_up:
291811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					*s++ = '9';
291911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					goto roundoff;
292011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					}
292111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				*s++ = dig + 1;
292211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				goto ret;
292311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
292411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			*s++ = dig;
292511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (i == ilim)
292611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				break;
292711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			b = multadd(b, 10, 0);
292811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (mlo == mhi)
292911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				mlo = mhi = multadd(mhi, 10, 0);
293011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			else {
293111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				mlo = multadd(mlo, 10, 0);
293211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				mhi = multadd(mhi, 10, 0);
293311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
293411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
293511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
293611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	else
293711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		for(i = 1;; i++) {
293811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			*s++ = dig = quorem(b,S) + '0';
293911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (i >= ilim)
294011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				break;
294111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			b = multadd(b, 10, 0);
294211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
294311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
294411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	/* Round off last digit */
294511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
294611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	b = lshift(b, 1);
294711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	j = cmp(b, S);
294811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (j > 0 || (j == 0 && dig & 1)) {
294911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert roundoff:
295011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		while(*--s == '9')
295111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (s == s0) {
295211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				k++;
295311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				*s++ = '1';
295411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				goto ret;
295511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				}
295611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		++*s++;
295711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
295811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	else {
295911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		while(*--s == '0');
296011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		s++;
296111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
296211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ret:
296311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Bfree(S);
296411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (mhi) {
296511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (mlo && mlo != mhi)
296611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			Bfree(mlo);
296711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		Bfree(mhi);
296811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
296911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ret1:
297011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Bfree(b);
297111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (s == s0) {				/* don't return empty string */
297211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*s++ = '0';
297311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		k = 0;
297411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
297511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	*s = 0;
297611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	*decpt = k + 1;
297711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (rve)
297811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*rve = s;
297911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return s0;
298011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
298111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
298211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <limits.h>
298311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
298411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert char *
298511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertrv_alloc(int i)
298611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
298711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int j, k, *r;
298811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
298911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	j = sizeof(ULong);
299011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	for(k = 0;
299111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i;
299211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		j <<= 1)
299311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			k++;
299411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	r = (int*)Balloc(k);
299511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	*r = k;
299611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return (char *)(r+1);
299711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
299811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
299911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert char *
300011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertnrv_alloc(char *s, char **rve, int n)
300111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
300211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	char *rv, *t;
300311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
300411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	t = rv = rv_alloc(n);
300511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	while((*t = *s++) !=0)
300611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		t++;
300711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (rve)
300811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*rve = t;
300911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return rv;
301011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
301111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
301211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
301311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* Strings values used by dtoa() */
301411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define	INFSTR	"Infinity"
301511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define	NANSTR	"NaN"
301611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
301711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define	DBL_ADJ		(DBL_MAX_EXP - 2 + ((DBL_MANT_DIG - 1) % 4))
301811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define	LDBL_ADJ	(LDBL_MAX_EXP - 2 + ((LDBL_MANT_DIG - 1) % 4))
301911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
302011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/*
302111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Round up the given digit string.  If the digit string is fff...f,
302211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * this procedure sets it to 100...0 and returns 1 to indicate that
302311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * the exponent needs to be bumped.  Otherwise, 0 is returned.
302411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
302511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic int
302611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertroundup(char *s0, int ndigits)
302711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
302811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	char *s;
302911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
303011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	for (s = s0 + ndigits - 1; *s == 0xf; s--) {
303111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (s == s0) {
303211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			*s = 1;
303311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			return (1);
303411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
303511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*s = 0;
303611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
303711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	++*s;
303811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return (0);
303911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
304011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
304111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/*
304211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Round the given digit string to ndigits digits according to the
304311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * current rounding mode.  Note that this could produce a string whose
304411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * value is not representable in the corresponding floating-point
304511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * type.  The exponent pointed to by decpt is adjusted if necessary.
304611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
304711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic void
304811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertdorounding(char *s0, int ndigits, int sign, int *decpt)
304911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
305011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int adjust = 0;	/* do we need to adjust the exponent? */
305111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
305211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	switch (FLT_ROUNDS) {
305311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	case 0:		/* toward zero */
305411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	default:	/* implementation-defined */
305511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		break;
305611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	case 1:		/* to nearest, halfway rounds to even */
305711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if ((s0[ndigits] > 8) ||
305811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		    (s0[ndigits] == 8 && s0[ndigits + 1] & 1))
305911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			adjust = roundup(s0, ndigits);
306011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		break;
306111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	case 2:		/* toward +inf */
306211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (sign == 0)
306311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			adjust = roundup(s0, ndigits);
306411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		break;
306511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	case 3:		/* toward -inf */
306611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (sign != 0)
306711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			adjust = roundup(s0, ndigits);
306811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		break;
306911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
307011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
307111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (adjust)
307211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*decpt += 4;
307311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
307411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
307511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/*
307611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * This procedure converts a double-precision number in IEEE format
307711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * into a string of hexadecimal digits and an exponent of 2.  Its
307811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * behavior is bug-for-bug compatible with dtoa() in mode 2, with the
307911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * following exceptions:
308011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
308111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * - An ndigits < 0 causes it to use as many digits as necessary to
308211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *   represent the number exactly.
308311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * - The additional xdigs argument should point to either the string
308411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *   "0123456789ABCDEF" or the string "0123456789abcdef", depending on
308511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *   which case is desired.
308611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * - This routine does not repeat dtoa's mistake of setting decpt
308711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *   to 9999 in the case of an infinity or NaN.  INT_MAX is used
308811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *   for this purpose instead.
308911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
309011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Note that the C99 standard does not specify what the leading digit
309111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * should be for non-zero numbers.  For instance, 0x1.3p3 is the same
309211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * as 0x2.6p2 is the same as 0x4.cp3.  This implementation chooses the
309311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * first digit so that subsequent digits are aligned on nibble
309411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * boundaries (before rounding).
309511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
309611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Inputs:	d, xdigs, ndigits
309711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Outputs:	decpt, sign, rve
309811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
309911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertchar *
310011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert__hdtoa(double d, const char *xdigs, int ndigits, int *decpt, int *sign,
310111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    char **rve)
310211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
310311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	static const int sigfigs = (DBL_MANT_DIG + 3) / 4;
310411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	union IEEEd2bits u;
310511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	char *s, *s0;
310611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int bufsize, f;
310711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
310811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	u.d = d;
310911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	*sign = u.bits.sign;
311011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
311111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	switch (f = fpclassify(d)) {
311211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	case FP_NORMAL:
311311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*decpt = u.bits.exp - DBL_ADJ;
311411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		break;
311511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	case FP_ZERO:
311611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertreturn_zero:
311711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*decpt = 1;
311811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		return (nrv_alloc("0", rve, 1));
311911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	case FP_SUBNORMAL:
312011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		/*
312111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		 * For processors that treat subnormals as zero, comparison
312211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		 * with zero will be equal, so we jump to the FP_ZERO case.
312311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		 */
312411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if(u.d == 0.0) goto return_zero;
312511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		u.d *= 0x1p514;
312611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*decpt = u.bits.exp - (514 + DBL_ADJ);
312711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		break;
312811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	case FP_INFINITE:
312911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*decpt = INT_MAX;
313011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		return (nrv_alloc(INFSTR, rve, sizeof(INFSTR) - 1));
313111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	case FP_NAN:
313211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*decpt = INT_MAX;
313311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		return (nrv_alloc(NANSTR, rve, sizeof(NANSTR) - 1));
313411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	default:
313511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef DEBUG
313611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		BugPrintf("fpclassify returned %d\n", f);
313711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
313811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		return 0; // FIXME??
313911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
314011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
314111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	/* FP_NORMAL or FP_SUBNORMAL */
314211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
314311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (ndigits == 0)		/* dtoa() compatibility */
314411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		ndigits = 1;
314511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
314611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	/*
314711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	 * For simplicity, we generate all the digits even if the
314811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	 * caller has requested fewer.
314911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	 */
315011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	bufsize = (sigfigs > ndigits) ? sigfigs : ndigits;
315111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	s0 = rv_alloc(bufsize);
315211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
315311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	/*
315411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	 * We work from right to left, first adding any requested zero
315511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	 * padding, then the least significant portion of the
315611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	 * mantissa, followed by the most significant.  The buffer is
315711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	 * filled with the byte values 0x0 through 0xf, which are
315811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	 * converted to xdigs[0x0] through xdigs[0xf] after the
315911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	 * rounding phase.
316011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	 */
316111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	for (s = s0 + bufsize - 1; s > s0 + sigfigs - 1; s--)
316211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*s = 0;
316311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	for (; s > s0 + sigfigs - (DBL_MANL_SIZE / 4) - 1 && s > s0; s--) {
316411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*s = u.bits.manl & 0xf;
316511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		u.bits.manl >>= 4;
316611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
316711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	for (; s > s0; s--) {
316811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*s = u.bits.manh & 0xf;
316911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		u.bits.manh >>= 4;
317011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
317111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
317211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	/*
317311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	 * At this point, we have snarfed all the bits in the
317411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	 * mantissa, with the possible exception of the highest-order
317511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	 * (partial) nibble, which is dealt with by the next
317611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	 * statement.  We also tack on the implicit normalization bit.
317711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	 */
317811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	*s = u.bits.manh | (1U << ((DBL_MANT_DIG - 1) % 4));
317911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
318011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	/* If ndigits < 0, we are expected to auto-size the precision. */
318111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (ndigits < 0) {
318211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		for (ndigits = sigfigs; s0[ndigits - 1] == 0; ndigits--)
318311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			;
318411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
318511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
318611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (sigfigs > ndigits && s0[ndigits] != 0)
318711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		dorounding(s0, ndigits, u.bits.sign, decpt);
318811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
318911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	s = s0 + ndigits;
319011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (rve != NULL)
319111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*rve = s;
319211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	*s-- = '\0';
319311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	for (; s >= s0; s--)
319411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*s = xdigs[(unsigned int)*s];
319511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
319611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return (s0);
319711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
319811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
319911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef NO_HEX_FP /*{*/
320011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
320111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic int
320211cd02dfb91661c65134cac258cf5924270e9d2Dan Albertgethex( CONST char **sp, CONST FPI *fpi, Long *exp, Bigint **bp, int sign, locale_t loc)
320311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
320411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Bigint *b;
320511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	CONST unsigned char *decpt, *s0, *s, *s1;
320611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	unsigned char *strunc;
320711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int big, esign, havedig, irv, j, k, n, n0, nbits, up, zret;
320811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	ULong L, lostbits, *x;
320911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	Long e, e1;
321011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef USE_LOCALE
321111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	int i;
321211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	NORMALIZE_LOCALE(loc);
321311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef NO_LOCALE_CACHE
321411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	const unsigned char *decimalpoint = (unsigned char*)localeconv_l(loc)->decimal_point;
321511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
321611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	const unsigned char *decimalpoint;
321711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	static unsigned char *decimalpoint_cache;
321811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (!(s0 = decimalpoint_cache)) {
321911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		s0 = (unsigned char*)localeconv_l(loc)->decimal_point;
322011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) {
322111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			strcpy(decimalpoint_cache, s0);
322211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			s0 = decimalpoint_cache;
322311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
322411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
322511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	decimalpoint = s0;
322611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
322711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
322811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
322911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef ANDROID_CHANGES
323011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (!hexdig['0'])
323111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		hexdig_init_D2A();
323211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
323311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
323411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	*bp = 0;
323511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	havedig = 0;
323611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	s0 = *(CONST unsigned char **)sp + 2;
323711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	while(s0[havedig] == '0')
323811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		havedig++;
323911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	s0 += havedig;
324011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	s = s0;
324111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	decpt = 0;
324211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	zret = 0;
324311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	e = 0;
324411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (hexdig[*s])
324511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		havedig++;
324611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	else {
324711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		zret = 1;
324811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef USE_LOCALE
324911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		for(i = 0; decimalpoint[i]; ++i) {
325011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (s[i] != decimalpoint[i])
325111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				goto pcheck;
325211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
325311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		decpt = s += i;
325411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
325511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (*s != '.')
325611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			goto pcheck;
325711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		decpt = ++s;
325811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
325911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (!hexdig[*s])
326011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			goto pcheck;
326111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		while(*s == '0')
326211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			s++;
326311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (hexdig[*s])
326411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			zret = 0;
326511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		havedig = 1;
326611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		s0 = s;
326711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
326811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	while(hexdig[*s])
326911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		s++;
327011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef USE_LOCALE
327111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (*s == *decimalpoint && !decpt) {
327211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		for(i = 1; decimalpoint[i]; ++i) {
327311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (s[i] != decimalpoint[i])
327411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				goto pcheck;
327511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
327611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		decpt = s += i;
327711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
327811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (*s == '.' && !decpt) {
327911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		decpt = ++s;
328011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
328111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		while(hexdig[*s])
328211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			s++;
328311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}/*}*/
328411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (decpt)
328511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		e = -(((Long)(s-decpt)) << 2);
328611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pcheck:
328711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	s1 = s;
328811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	big = esign = 0;
328911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	switch(*s) {
329011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  case 'p':
329111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  case 'P':
329211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		switch(*++s) {
329311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		  case '-':
329411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			esign = 1;
329511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			/* no break */
329611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		  case '+':
329711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			s++;
329811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		  }
329911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if ((n = hexdig[*s]) == 0 || n > 0x19) {
330011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			s = s1;
330111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			break;
330211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
330311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		e1 = n - 0x10;
330411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		while((n = hexdig[*++s]) !=0 && n <= 0x19) {
330511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (e1 & 0xf8000000)
330611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				big = 1;
330711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			e1 = 10*e1 + n - 0x10;
330811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
330911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (esign)
331011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			e1 = -e1;
331111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		e += e1;
331211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  }
331311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	*sp = (char*)s;
331411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (!havedig)
331511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*sp = (char*)s0 - 1;
331611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (zret)
331711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		return STRTOG_Zero;
331811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (big) {
331911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (esign) {
332011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			switch(fpi->rounding) {
332111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			  case FPI_Round_up:
332211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (sign)
332311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					break;
332411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				goto ret_tiny;
332511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			  case FPI_Round_down:
332611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (!sign)
332711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					break;
332811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				goto ret_tiny;
332911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			  }
333011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			goto retz;
333111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ret_tiny:
333211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			b = Balloc(0);
333311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			b->wds = 1;
333411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			b->x[0] = 1;
333511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			goto dret;
333611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
333711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		switch(fpi->rounding) {
333811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		  case FPI_Round_near:
333911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			goto ovfl1;
334011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		  case FPI_Round_up:
334111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (!sign)
334211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				goto ovfl1;
334311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			goto ret_big;
334411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		  case FPI_Round_down:
334511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (sign)
334611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				goto ovfl1;
334711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			goto ret_big;
334811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		  }
334911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ret_big:
335011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		nbits = fpi->nbits;
335111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		n0 = n = nbits >> kshift;
335211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (nbits & kmask)
335311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			++n;
335411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		for(j = n, k = 0; j >>= 1; ++k);
335511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*bp = b = Balloc(k);
335611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		b->wds = n;
335711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		for(j = 0; j < n0; ++j)
335811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			b->x[j] = ALL_ON;
335911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (n > n0)
336011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			b->x[j] = ULbits >> (ULbits - (nbits & kmask));
336111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		*exp = fpi->emin;
336211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		return STRTOG_Normal | STRTOG_Inexlo;
336311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
336411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	/*
336511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	 * Truncate the hex string if it is longer than the precision needed,
336611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	 * to avoid denial-of-service issues with very large strings.  Use
336711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	 * additional digits to insure precision.  Scan to-be-truncated digits
336811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	 * and replace with either '1' or '0' to ensure proper rounding.
336911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	 */
337011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	{
337111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		int maxdigits = ((fpi->nbits + 3) >> 2) + 2;
337211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		size_t nd = s1 - s0;
337311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef USE_LOCALE
337411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		int dplen = strlen((const char *)decimalpoint);
337511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
337611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		int dplen = 1;
337711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
337811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
337911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (decpt && s0 < decpt)
338011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			nd -= dplen;
338111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (nd > maxdigits && (strunc = alloca(maxdigits + dplen + 2)) != NULL) {
338211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			ssize_t nd0 = decpt ? decpt - s0 - dplen : nd;
338311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			unsigned char *tp = strunc + maxdigits;
338411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			int found = 0;
338511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if ((nd0 -= maxdigits) >= 0 || s0 >= decpt)
338611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				memcpy(strunc, s0, maxdigits);
338711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			else {
338811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				memcpy(strunc, s0, maxdigits + dplen);
338911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				tp += dplen;
339011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				}
339111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			s0 += maxdigits;
339211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			e += (nd - (maxdigits + 1)) << 2;
339311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (nd0 > 0) {
339411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				while(nd0-- > 0)
339511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					if (*s0++ != '0') {
339611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert						found++;
339711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert						break;
339811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert						}
339911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				s0 += dplen;
340011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				}
340111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (!found && decpt) {
340211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				while(s0 < s1)
340311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					if(*s0++ != '0') {
340411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert						found++;
340511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert						break;
340611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert						}
340711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				}
340811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			*tp++ = found ? '1' : '0';
340911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			*tp = 0;
341011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			s0 = strunc;
341111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			s1 = tp;
341211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
341311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
341411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
341511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	n = s1 - s0 - 1;
341611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	for(k = 0; n > (1 << (kshift-2)) - 1; n >>= 1)
341711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		k++;
341811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	b = Balloc(k);
341911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	x = b->x;
342011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	n = 0;
342111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	L = 0;
342211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef USE_LOCALE
342311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	for(i = 0; decimalpoint[i+1]; ++i);
342411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
342511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	while(s1 > s0) {
342611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef USE_LOCALE
342711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (*--s1 == decimalpoint[i]) {
342811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			s1 -= i;
342911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			continue;
343011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
343111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
343211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (*--s1 == '.')
343311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			continue;
343411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
343511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (n == ULbits) {
343611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			*x++ = L;
343711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			L = 0;
343811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			n = 0;
343911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
344011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		L |= (hexdig[*s1] & 0x0f) << n;
344111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		n += 4;
344211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
344311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	*x++ = L;
344411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	b->wds = n = x - b->x;
344511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	n = ULbits*n - hi0bits(L);
344611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	nbits = fpi->nbits;
344711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	lostbits = 0;
344811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	x = b->x;
344911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (n > nbits) {
345011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		n -= nbits;
345111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (any_on(b,n)) {
345211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			lostbits = 1;
345311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			k = n - 1;
345411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (x[k>>kshift] & 1 << (k & kmask)) {
345511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				lostbits = 2;
345611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (k > 0 && any_on(b,k))
345711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					lostbits = 3;
345811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				}
345911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
346011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		rshift(b, n);
346111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		e += n;
346211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
346311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	else if (n < nbits) {
346411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		n = nbits - n;
346511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		b = lshift(b, n);
346611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		e -= n;
346711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		x = b->x;
346811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
346911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (e > fpi->emax) {
347011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ovfl:
347111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		Bfree(b);
347211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ovfl1:
347311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef NO_ERRNO
347411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		errno = ERANGE;
347511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
347611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		return STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi;
347711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
347811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	irv = STRTOG_Normal;
347911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (e < fpi->emin) {
348011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		irv = STRTOG_Denormal;
348111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		n = fpi->emin - e;
348211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (n >= nbits) {
348311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			switch (fpi->rounding) {
348411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			  case FPI_Round_near:
348511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (n == nbits && (n < 2 || any_on(b,n-1)))
348611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					goto one_bit;
348711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				break;
348811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			  case FPI_Round_up:
348911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (!sign)
349011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					goto one_bit;
349111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				break;
349211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			  case FPI_Round_down:
349311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (sign) {
349411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert one_bit:
349511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					x[0] = b->wds = 1;
349611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert dret:
349711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					*bp = b;
349811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					*exp = fpi->emin;
349911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef NO_ERRNO
350011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					errno = ERANGE;
350111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
350211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					return STRTOG_Denormal | STRTOG_Inexhi
350311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert						| STRTOG_Underflow;
350411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					}
350511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			  }
350611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			Bfree(b);
350711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert retz:
350811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef NO_ERRNO
350911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			errno = ERANGE;
351011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
351111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			return STRTOG_Zero | STRTOG_Inexlo | STRTOG_Underflow;
351211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
351311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		k = n - 1;
351411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (lostbits)
351511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			lostbits = 1;
351611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		else if (k > 0)
351711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			lostbits = any_on(b,k);
351811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (x[k>>kshift] & 1 << (k & kmask))
351911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			lostbits |= 2;
352011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		nbits -= n;
352111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		rshift(b,n);
352211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		e = fpi->emin;
352311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
352411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (lostbits) {
352511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		up = 0;
352611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		switch(fpi->rounding) {
352711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		  case FPI_Round_zero:
352811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			break;
352911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		  case FPI_Round_near:
353011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (lostbits & 2
353111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			 && (lostbits | x[0]) & 1)
353211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				up = 1;
353311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			break;
353411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		  case FPI_Round_up:
353511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			up = 1 - sign;
353611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			break;
353711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		  case FPI_Round_down:
353811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			up = sign;
353911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		  }
354011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		if (up) {
354111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			k = b->wds;
354211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			b = increment(b);
354311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			x = b->x;
354411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			if (irv == STRTOG_Denormal) {
354511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (nbits == fpi->nbits - 1
354611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				 && x[nbits >> kshift] & 1 << (nbits & kmask))
354711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					irv =  STRTOG_Normal;
354811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				}
354911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			else if (b->wds > k
355011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			 || ((n = nbits & kmask) !=0
355111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			      && hi0bits(x[k-1]) < 32-n)) {
355211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				rshift(b,1);
355311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				if (++e > fpi->emax)
355411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					goto ovfl;
355511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				}
355611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			irv |= STRTOG_Inexhi;
355711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			}
355811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		else
355911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			irv |= STRTOG_Inexlo;
356011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert		}
356111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	*bp = b;
356211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	*exp = e;
356311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return irv;
356411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
356511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
356611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif /*}*/
356711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
356811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef __cplusplus
356911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
357011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
3571