11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*	$NetBSD: strtod.c,v 1.45.2.1 2005/04/19 13:35:54 tron Exp $	*/
21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/****************************************************************
41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * The author of this software is David M. Gay.
61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (c) 1991 by AT&T.
81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Permission to use, copy, modify, and distribute this software for any
101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * purpose without fee is hereby granted, provided that this entire notice
111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * is included in all copies of any software which is or includes a copy
121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * or modification of this software and in all copies of the supporting
131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * documentation for such software.
141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ***************************************************************/
211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Please send bug reports to
231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	David M. Gay
241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	AT&T Bell Laboratories, Room 2C-463
251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	600 Mountain Avenue
261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	Murray Hill, NJ 07974-2070
271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	U.S.A.
281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	dmg@research.att.com or research!dmg
291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* strtod for IEEE-, VAX-, and IBM-arithmetic machines.
321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * This strtod returns a nearest machine number to the input decimal
341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * string (or sets errno to ERANGE).  With IEEE arithmetic, ties are
351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * broken by the IEEE round-even rule.  Otherwise ties are broken by
361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * biased rounding (add half and chop).
371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Inspired loosely by William D. Clinger's paper "How to Read Floating
391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Modifications:
421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	1. We only require IEEE, IBM, or VAX double-precision
441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *		arithmetic (not IEEE double-extended).
451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	2. We get by with floating-point arithmetic in a case that
461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *		Clinger missed -- when we're computing d * 10^n
471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *		for a small integer d and the integer n is not too
481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *		much larger than 22 (the maximum integer k for which
491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *		we can represent 10^k exactly), we may be able to
501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *		compute (d*10^k) * 10^(e-k) with just one roundoff.
511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	3. Rather than a bit-at-a-time adjustment of the binary
521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *		result in the hard case, we use floating-point
531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *		arithmetic to determine the adjustment to within
541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *		one bit; only in really hard cases do we need to
551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *		compute a second residual.
561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	4. Because of 3., we don't need a large table of powers of 10
571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *		for ten-to-e (just some small tables, e.g. of 10^k
581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *		for 0 <= k <= 22).
591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * #define IEEE_LITTLE_ENDIAN for IEEE-arithmetic machines where the least
631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	significant byte has the lowest address.
641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * #define IEEE_BIG_ENDIAN for IEEE-arithmetic machines where the most
651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	significant byte has the lowest address.
661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * #define Long int on machines with 32-bit ints and 64-bit longs.
671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * #define Sudden_Underflow for IEEE-format machines without gradual
681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	underflow (i.e., that flush to zero on underflow).
691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * #define IBM for IBM mainframe-style floating-point arithmetic.
701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * #define VAX for VAX-style floating-point arithmetic.
711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * #define Unsigned_Shifts if >> does treats its left operand as unsigned.
721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * #define No_leftright to omit left-right logic in fast floating-point
731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	computation of dtoa.
741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3.
751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines
761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	that use extended-precision instructions to compute rounded
771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	products and quotients) with IBM.
781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * #define ROUND_BIASED for IEEE-format with biased rounding.
791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * #define Inaccurate_Divide for IEEE-format with correctly rounded
801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	products but inaccurate quotients, e.g., for Intel i860.
811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * #define Just_16 to store 16 bits per 32-bit Long when doing high-precision
821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	integer arithmetic.  Whether this speeds things up or slows things
831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	down depends on the machine and the number being converted.
841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * #define KR_headers for old-style C function headers.
851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * #define Bad_float_h if your system lacks a float.h or if it does not
861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP,
871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	FLT_RADIX, FLT_ROUNDS, and DBL_MAX.
881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n)
891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	if memory is available and otherwise does something you deem
901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	appropriate.  If MALLOC is undefined, malloc will be invoked
911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	directly -- and assumed always to succeed.
921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef ANDROID_CHANGES
951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <pthread.h>
961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define mutex_lock(x) pthread_mutex_lock(x)
971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define mutex_unlock(x) pthread_mutex_unlock(x)
981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/cdefs.h>
1011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if defined(LIBC_SCCS) && !defined(lint)
1021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project__RCSID("$NetBSD: strtod.c,v 1.45.2.1 2005/04/19 13:35:54 tron Exp $");
1031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* LIBC_SCCS and not lint */
1041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Unsigned_Shifts
1061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \
1071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    defined(__mips__) || defined(__ns32k__) || defined(__alpha__) || \
1081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    defined(__powerpc__) || defined(__sh__) || defined(__x86_64__) || \
1091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    defined(__hppa__) || \
1101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    (defined(__arm__) && defined(__VFP_FP__))
1111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <endian.h>
1121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if BYTE_ORDER == BIG_ENDIAN
1131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define IEEE_BIG_ENDIAN
1141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
1151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define IEEE_LITTLE_ENDIAN
1161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if defined(__arm__) && !defined(__VFP_FP__)
1201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
1211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Although the CPU is little endian the FP has different
1221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * byte and word endianness. The byte order is still little endian
1231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * but the word order is big endian.
1241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
1251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define IEEE_BIG_ENDIAN
1261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef __vax__
1291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define VAX
1301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if defined(__hppa__) || defined(__mips__) || defined(__sh__)
1331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	NAN_WORD0	0x7ff40000
1341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
1351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	NAN_WORD0	0x7ff80000
1361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	NAN_WORD1	0
1381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Long	int32_t
1401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define ULong	u_int32_t
1411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef DEBUG
1431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "stdio.h"
1441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
1451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef __cplusplus
1481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "malloc.h"
1491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "memory.h"
1501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
1511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef KR_headers
1521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "stdlib.h"
1531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "string.h"
1541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef ANDROID_CHANGES
1551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "locale.h"
1561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* ANDROID_CHANGES */
1571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
1581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "malloc.h"
1591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "memory.h"
1601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef ANDROID_CHANGES
1631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "extern.h"
1641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "reentrant.h"
1651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* ANDROID_CHANGES */
1661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef MALLOC
1681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef KR_headers
1691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern char *MALLOC();
1701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
1711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern void *MALLOC(size_t);
1721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
1741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define MALLOC malloc
1751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "ctype.h"
1781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "errno.h"
1791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "float.h"
1801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef __MATH_H__
1821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "math.h"
1831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef __cplusplus
1861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern "C" {
1871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef CONST
1901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef KR_headers
1911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define CONST /* blank */
1921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
1931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define CONST const
1941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef Unsigned_Shifts
1981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Sign_Extend(a,b) if (b < 0) a |= 0xffff0000;
1991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
2001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Sign_Extend(a,b) /*no-op*/
2011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
2021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + \
2041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    defined(IBM) != 1
2051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectExactly one of IEEE_LITTLE_ENDIAN IEEE_BIG_ENDIAN, VAX, or
2061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectIBM should be defined.
2071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
2081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projecttypedef union {
2101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	double d;
2111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ULong ul[2];
2121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} _double;
2131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define value(x) ((x).d)
2141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef IEEE_LITTLE_ENDIAN
2151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define word0(x) ((x).ul[1])
2161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define word1(x) ((x).ul[0])
2171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
2181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define word0(x) ((x).ul[0])
2191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define word1(x) ((x).ul[1])
2201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
2211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* The following definition of Storeinc is appropriate for MIPS processors.
2231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * An alternative that might be better on some machines is
2241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
2251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
2261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) + defined(__arm__)
2271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Storeinc(a,b,c) \
2281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    (((u_short *)(void *)a)[1] = \
2291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(u_short)b, ((u_short *)(void *)a)[0] = (u_short)c, a++)
2301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
2311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Storeinc(a,b,c) \
2321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    (((u_short *)(void *)a)[0] = \
2331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(u_short)b, ((u_short *)(void *)a)[1] = (u_short)c, a++)
2341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
2351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* #define P DBL_MANT_DIG */
2371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Ten_pmax = floor(P*log(2)/log(5)) */
2381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
2391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
2401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
2411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN)
2431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Exp_shift  20
2441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Exp_shift1 20
2451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Exp_msk1    0x100000
2461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Exp_msk11   0x100000
2471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Exp_mask  0x7ff00000
2481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define P 53
2491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Bias 1023
2501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define IEEE_Arith
2511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Emin (-1022)
2521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Exp_1  0x3ff00000
2531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Exp_11 0x3ff00000
2541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Ebits 11
2551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Frac_mask  0xfffff
2561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Frac_mask1 0xfffff
2571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Ten_pmax 22
2581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Bletch 0x10
2591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Bndry_mask  0xfffff
2601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Bndry_mask1 0xfffff
2611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define LSB 1
2621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Sign_bit 0x80000000
2631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Log2P 1
2641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Tiny0 0
2651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Tiny1 1
2661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Quick_max 14
2671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Int_max 14
2681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Infinite(x) (word0(x) == 0x7ff00000) /* sufficient test for here */
2691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
2701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#undef  Sudden_Underflow
2711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Sudden_Underflow
2721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef IBM
2731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Exp_shift  24
2741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Exp_shift1 24
2751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Exp_msk1   0x1000000
2761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Exp_msk11  0x1000000
2771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Exp_mask  0x7f000000
2781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define P 14
2791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Bias 65
2801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Exp_1  0x41000000
2811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Exp_11 0x41000000
2821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Ebits 8	/* exponent has 7 bits, but 8 is the right value in b2d */
2831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Frac_mask  0xffffff
2841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Frac_mask1 0xffffff
2851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Bletch 4
2861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Ten_pmax 22
2871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Bndry_mask  0xefffff
2881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Bndry_mask1 0xffffff
2891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define LSB 1
2901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Sign_bit 0x80000000
2911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Log2P 4
2921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Tiny0 0x100000
2931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Tiny1 0
2941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Quick_max 14
2951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Int_max 15
2961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else /* VAX */
2971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Exp_shift  23
2981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Exp_shift1 7
2991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Exp_msk1    0x80
3001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Exp_msk11   0x800000
3011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Exp_mask  0x7f80
3021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define P 56
3031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Bias 129
3041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Exp_1  0x40800000
3051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Exp_11 0x4080
3061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Ebits 8
3071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Frac_mask  0x7fffff
3081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Frac_mask1 0xffff007f
3091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Ten_pmax 24
3101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Bletch 2
3111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Bndry_mask  0xffff007f
3121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Bndry_mask1 0xffff007f
3131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define LSB 0x10000
3141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Sign_bit 0x8000
3151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Log2P 1
3161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Tiny0 0x80
3171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Tiny1 0
3181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Quick_max 15
3191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Int_max 15
3201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
3211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
3221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef IEEE_Arith
3241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define ROUND_BIASED
3251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
3261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef RND_PRODQUOT
3281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define rounded_product(a,b) a = rnd_prod(a, b)
3291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define rounded_quotient(a,b) a = rnd_quot(a, b)
3301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef KR_headers
3311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern double rnd_prod(), rnd_quot();
3321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
3331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern double rnd_prod(double, double), rnd_quot(double, double);
3341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
3351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
3361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define rounded_product(a,b) a *= b
3371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define rounded_quotient(a,b) a /= b
3381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
3391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
3411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Big1 0xffffffff
3421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef Just_16
3441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* When Pack_32 is not defined, we store 16 bits per 32-bit Long.
3451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * This makes some inner loops simpler and sometimes saves work
3461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * during multiplications, but it often seems to make things slightly
3471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * slower.  Hence the default is now to store 32 bits per Long.
3481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
3491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef Pack_32
3501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Pack_32
3511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
3521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
3531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define Kmax 15
3551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef __cplusplus
3571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern "C" double strtod(const char *s00, char **se);
3581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern "C" char *__dtoa(double d, int mode, int ndigits,
3591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			int *decpt, int *sign, char **rve);
3601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
3611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct
3631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectBigint {
3641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	struct Bigint *next;
3651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int k, maxwds, sign, wds;
3661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ULong x[1];
367e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa};
3681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project typedef struct Bigint Bigint;
3701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project static Bigint *freelist[Kmax+1];
3721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef ANDROID_CHANGES
3741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project static pthread_mutex_t freelist_mutex = PTHREAD_MUTEX_INITIALIZER;
3751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
3761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef _REENTRANT
3771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project static mutex_t freelist_mutex = MUTEX_INITIALIZER;
3781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
3791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
3801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3818132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner/* Special value used to indicate an invalid Bigint value,
3828132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner * e.g. when a memory allocation fails. The idea is that we
3838132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner * want to avoid introducing NULL checks everytime a bigint
3848132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner * computation is performed. Also the NULL value can also be
3858132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner * already used to indicate "value not initialized yet" and
3868132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner * returning NULL might alter the execution code path in
3878132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner * case of OOM.
3888132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner */
3898132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner#define  BIGINT_INVALID   ((Bigint *)&bigint_invalid_value)
3908132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner
3918132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turnerstatic const Bigint bigint_invalid_value;
3928132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner
3938132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner
3948132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner/* Return BIGINT_INVALID on allocation failure.
3958132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner *
3968132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner * Most of the code here depends on the fact that this function
3978132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner * never returns NULL.
3988132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner */
3991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project static Bigint *
4001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectBalloc
4011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef KR_headers
4021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(k) int k;
4031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
4041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(int k)
4051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
4061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
4071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int x;
4081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	Bigint *rv;
4091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	mutex_lock(&freelist_mutex);
4111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if ((rv = freelist[k]) != NULL) {
4131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		freelist[k] = rv->next;
414e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
4151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	else {
4161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		x = 1 << k;
4171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(Long));
4188132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		if (rv == NULL) {
4198132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		        rv = BIGINT_INVALID;
4208132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner			goto EXIT;
4218132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		}
4221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		rv->k = k;
4231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		rv->maxwds = x;
424e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
4251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	rv->sign = rv->wds = 0;
4268132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' TurnerEXIT:
4271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	mutex_unlock(&freelist_mutex);
4281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return rv;
430e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa}
4311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project static void
4331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectBfree
4341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef KR_headers
4351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(v) Bigint *v;
4361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
4371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(Bigint *v)
4381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
4391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
4408132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner	if (v && v != BIGINT_INVALID) {
4411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		mutex_lock(&freelist_mutex);
4421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		v->next = freelist[v->k];
4441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		freelist[v->k] = v;
4451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		mutex_unlock(&freelist_mutex);
4471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
448e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa}
4491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4508132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner#define Bcopy_valid(x,y) memcpy(&(x)->sign, &(y)->sign, \
4518132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner    (y)->wds*sizeof(Long) + 2*sizeof(int))
4528132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner
4538132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner#define Bcopy(x,y)  Bcopy_ptr(&(x),(y))
4548132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner
4558132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner static void
4568132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' TurnerBcopy_ptr(Bigint **px, Bigint *y)
4578132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner{
4588132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner	if (*px == BIGINT_INVALID)
4598132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		return; /* no space to store copy */
4608132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner	if (y == BIGINT_INVALID) {
4618132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		Bfree(*px); /* invalid input */
4628132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		*px = BIGINT_INVALID;
4638132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner	} else {
4648132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		Bcopy_valid(*px,y);
4658132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner	}
4668132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner}
4671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project static Bigint *
4691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectmultadd
4701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef KR_headers
4711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(b, m, a) Bigint *b; int m, a;
4721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
4731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(Bigint *b, int m, int a)	/* multiply by m and add a */
4741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
4751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
4761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int i, wds;
4771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ULong *x, y;
4781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef Pack_32
4791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ULong xi, z;
4801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
4811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	Bigint *b1;
4821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4838132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner	if (b == BIGINT_INVALID)
4848132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		return b;
4858132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner
4861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	wds = b->wds;
4871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	x = b->x;
4881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	i = 0;
4891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	do {
4901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef Pack_32
4911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		xi = *x;
4921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		y = (xi & 0xffff) * m + a;
4931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		z = (xi >> 16) * m + (y >> 16);
4941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		a = (int)(z >> 16);
4951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*x++ = (z << 16) + (y & 0xffff);
4961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
4971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		y = *x * m + a;
4981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		a = (int)(y >> 16);
4991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*x++ = y & 0xffff;
5001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
501e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
502e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	while(++i < wds);
5031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (a) {
5041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (wds >= b->maxwds) {
5051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			b1 = Balloc(b->k+1);
5068132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner			if (b1 == BIGINT_INVALID) {
5078132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner				Bfree(b);
5088132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner				return b1;
5098132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner			}
5108132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner			Bcopy_valid(b1, b);
5111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			Bfree(b);
5121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			b = b1;
5131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
5141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		b->x[wds++] = a;
5151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		b->wds = wds;
5161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
517e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	return b;
518e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa}
5191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
5201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project static Bigint *
5211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projects2b
5221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef KR_headers
5231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9;
5241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
5251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(CONST char *s, int nd0, int nd, ULong y9)
5261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
5271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
5281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	Bigint *b;
5291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int i, k;
5301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	Long x, y;
5311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
5321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	x = (nd + 8) / 9;
5331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	for(k = 0, y = 1; x > y; y <<= 1, k++) ;
5341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef Pack_32
5351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	b = Balloc(k);
5368132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner	if (b == BIGINT_INVALID)
5378132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		return b;
5381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	b->x[0] = y9;
5391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	b->wds = 1;
5401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
5411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	b = Balloc(k+1);
5428132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner	if (b == BIGINT_INVALID)
5438132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		return b;
5448132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner
5451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	b->x[0] = y9 & 0xffff;
5461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
5471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
5481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
5491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	i = 9;
5501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (9 < nd0) {
5511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		s += 9;
5521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		do b = multadd(b, 10, *s++ - '0');
5531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			while(++i < nd0);
5541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		s++;
555e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
5561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	else
5571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		s += 10;
5581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	for(; i < nd; i++)
5591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		b = multadd(b, 10, *s++ - '0');
5601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return b;
561e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa}
5621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
5631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project static int
5641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projecthi0bits
5651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef KR_headers
5661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(x) ULong x;
5671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
5681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(ULong x)
5691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
5701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
5711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int k = 0;
5721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
5731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (!(x & 0xffff0000)) {
5741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		k = 16;
5751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		x <<= 16;
576e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
5771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (!(x & 0xff000000)) {
5781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		k += 8;
5791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		x <<= 8;
580e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
5811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (!(x & 0xf0000000)) {
5821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		k += 4;
5831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		x <<= 4;
584e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
5851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (!(x & 0xc0000000)) {
5861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		k += 2;
5871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		x <<= 2;
588e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
5891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (!(x & 0x80000000)) {
5901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		k++;
5911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (!(x & 0x40000000))
5921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return 32;
5931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
594e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	return k;
595e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa}
5961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
5971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project static int
5981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectlo0bits
5991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef KR_headers
6001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(y) ULong *y;
6011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
6021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(ULong *y)
6031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
6041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
6051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int k;
6061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ULong x = *y;
6071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
6081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (x & 7) {
6091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (x & 1)
6101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return 0;
6111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (x & 2) {
6121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			*y = x >> 1;
6131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return 1;
6141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
6151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*y = x >> 2;
6161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return 2;
617e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
6181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	k = 0;
6191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (!(x & 0xffff)) {
6201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		k = 16;
6211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		x >>= 16;
622e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
6231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (!(x & 0xff)) {
6241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		k += 8;
6251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		x >>= 8;
626e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
6271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (!(x & 0xf)) {
6281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		k += 4;
6291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		x >>= 4;
630e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
6311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (!(x & 0x3)) {
6321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		k += 2;
6331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		x >>= 2;
634e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
6351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (!(x & 1)) {
6361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		k++;
6371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		x >>= 1;
6381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (!x & 1)
6391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return 32;
640e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
6411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*y = x;
6421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return k;
643e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa}
6441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
6451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project static Bigint *
6461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projecti2b
6471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef KR_headers
6481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(i) int i;
6491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
6501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(int i)
6511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
6521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
6531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	Bigint *b;
6541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
6551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	b = Balloc(1);
6568132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner	if (b != BIGINT_INVALID) {
6578132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		b->x[0] = i;
6588132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		b->wds = 1;
6598132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		}
6601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return b;
661e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa}
6621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
6631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project static Bigint *
6641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectmult
6651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef KR_headers
6661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(a, b) Bigint *a, *b;
6671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
6681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(Bigint *a, Bigint *b)
6691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
6701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
6711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	Bigint *c;
6721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int k, wa, wb, wc;
6731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ULong carry, y, z;
6741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
6751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef Pack_32
6761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ULong z2;
6771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
6781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
6798132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner	if (a == BIGINT_INVALID || b == BIGINT_INVALID)
6808132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		return BIGINT_INVALID;
6818132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner
6821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (a->wds < b->wds) {
6831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		c = a;
6841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		a = b;
6851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		b = c;
686e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
6871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	k = a->k;
6881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	wa = a->wds;
6891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	wb = b->wds;
6901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	wc = wa + wb;
6911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (wc > a->maxwds)
6921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		k++;
6931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	c = Balloc(k);
6948132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner	if (c == BIGINT_INVALID)
6958132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		return c;
6961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	for(x = c->x, xa = x + wc; x < xa; x++)
6971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*x = 0;
6981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	xa = a->x;
6991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	xae = xa + wa;
7001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	xb = b->x;
7011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	xbe = xb + wb;
7021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	xc0 = c->x;
7031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef Pack_32
7041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	for(; xb < xbe; xb++, xc0++) {
7051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if ((y = *xb & 0xffff) != 0) {
7061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			x = xa;
7071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			xc = xc0;
7081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			carry = 0;
7091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			do {
7101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
7111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				carry = z >> 16;
7121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
7131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				carry = z2 >> 16;
7141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				Storeinc(xc, z2, z);
7151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
716e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa			while(x < xae);
717e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa			*xc = carry;
718e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
7191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if ((y = *xb >> 16) != 0) {
7201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			x = xa;
7211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			xc = xc0;
7221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			carry = 0;
7231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			z2 = *xc;
7241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			do {
7251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				z = (*x & 0xffff) * y + (*xc >> 16) + carry;
7261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				carry = z >> 16;
7271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				Storeinc(xc, z, z2);
7281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
7291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				carry = z2 >> 16;
7301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
731e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa			while(x < xae);
732e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa			*xc = z2;
7331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
734e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
7351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
7361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	for(; xb < xbe; xc0++) {
7371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (y = *xb++) {
7381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			x = xa;
7391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			xc = xc0;
7401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			carry = 0;
7411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			do {
7421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				z = *x++ * y + *xc + carry;
7431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				carry = z >> 16;
7441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*xc++ = z & 0xffff;
7451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
746e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa			while(x < xae);
747e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa			*xc = carry;
7481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
749e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
7501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
7511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
7521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	c->wds = wc;
7531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return c;
754e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa}
7551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
7561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project static Bigint *p5s;
757144a5d3c86acdebeb3af53c03325a85d44b06679Glenn Kasten static pthread_mutex_t p5s_mutex = PTHREAD_MUTEX_INITIALIZER;
7581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
7591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project static Bigint *
7601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectpow5mult
7611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef KR_headers
7621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(b, k) Bigint *b; int k;
7631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
7641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(Bigint *b, int k)
7651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
7661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
7671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	Bigint *b1, *p5, *p51;
7681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int i;
7691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	static const int p05[3] = { 5, 25, 125 };
7701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
7718132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner	if (b == BIGINT_INVALID)
7728132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		return b;
7738132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner
7741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if ((i = k & 3) != 0)
7751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		b = multadd(b, p05[i-1], 0);
7761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
7771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (!(k = (unsigned int) k >> 2))
7781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return b;
779144a5d3c86acdebeb3af53c03325a85d44b06679Glenn Kasten	mutex_lock(&p5s_mutex);
7801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (!(p5 = p5s)) {
7811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/* first time */
7828132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		p5 = i2b(625);
7838132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		if (p5 == BIGINT_INVALID) {
7848132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner			Bfree(b);
785144a5d3c86acdebeb3af53c03325a85d44b06679Glenn Kasten			mutex_unlock(&p5s_mutex);
7868132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner			return p5;
7878132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		}
7888132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		p5s = p5;
7891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		p5->next = 0;
790e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
7911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	for(;;) {
7921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (k & 1) {
7931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			b1 = mult(b, p5);
7941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			Bfree(b);
7951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			b = b1;
796e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
7971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (!(k = (unsigned int) k >> 1))
7981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
7991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (!(p51 = p5->next)) {
8008132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner			p51 = mult(p5,p5);
8018132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner			if (p51 == BIGINT_INVALID) {
8028132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner				Bfree(b);
803144a5d3c86acdebeb3af53c03325a85d44b06679Glenn Kasten				mutex_unlock(&p5s_mutex);
8048132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner				return p51;
8058132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner			}
8068132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner			p5->next = p51;
8071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			p51->next = 0;
8081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
809e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		p5 = p51;
8101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
811144a5d3c86acdebeb3af53c03325a85d44b06679Glenn Kasten	mutex_unlock(&p5s_mutex);
812e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	return b;
813e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa}
8141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
8151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project static Bigint *
8161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectlshift
8171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef KR_headers
8181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(b, k) Bigint *b; int k;
8191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
8201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(Bigint *b, int k)
8211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
8221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
8231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int i, k1, n, n1;
8241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	Bigint *b1;
8251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ULong *x, *x1, *xe, z;
8261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
8278132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner	if (b == BIGINT_INVALID)
8288132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		return b;
8298132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner
8301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef Pack_32
8311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	n = (unsigned int)k >> 5;
8321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
8331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	n = (unsigned int)k >> 4;
8341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
8351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	k1 = b->k;
8361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	n1 = n + b->wds + 1;
8371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	for(i = b->maxwds; n1 > i; i <<= 1)
8381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		k1++;
8391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	b1 = Balloc(k1);
8408132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner	if (b1 == BIGINT_INVALID) {
8418132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		Bfree(b);
8428132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		return b1;
8438132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner	}
8441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	x1 = b1->x;
8451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	for(i = 0; i < n; i++)
8461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*x1++ = 0;
8471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	x = b->x;
8481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	xe = x + b->wds;
8491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef Pack_32
8501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (k &= 0x1f) {
8511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		k1 = 32 - k;
8521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		z = 0;
8531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		do {
8541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			*x1++ = *x << k | z;
8551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			z = *x++ >> k1;
856e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
857e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		while(x < xe);
8581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if ((*x1 = z) != 0)
8591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			++n1;
860e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
8611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
8621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (k &= 0xf) {
8631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		k1 = 16 - k;
8641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		z = 0;
8651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		do {
8661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			*x1++ = *x << k  & 0xffff | z;
8671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			z = *x++ >> k1;
868e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
869e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		while(x < xe);
8701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (*x1 = z)
8711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			++n1;
872e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
8731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
8741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	else do
8751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*x1++ = *x++;
8761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		while(x < xe);
8771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	b1->wds = n1 - 1;
8781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	Bfree(b);
8791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return b1;
880e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa}
8811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
8821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project static int
8831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectcmp
8841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef KR_headers
8851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(a, b) Bigint *a, *b;
8861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
8871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(Bigint *a, Bigint *b)
8881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
8891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
8901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ULong *xa, *xa0, *xb, *xb0;
8911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int i, j;
8921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
8938132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner	if (a == BIGINT_INVALID || b == BIGINT_INVALID)
8948132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner#ifdef DEBUG
8958132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		Bug("cmp called with a or b invalid");
8968132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner#else
8978132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		return 0; /* equal - the best we can do right now */
8988132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner#endif
8998132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner
9001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	i = a->wds;
9011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	j = b->wds;
9021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef DEBUG
9031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (i > 1 && !a->x[i-1])
9041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		Bug("cmp called with a->x[a->wds-1] == 0");
9051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (j > 1 && !b->x[j-1])
9061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		Bug("cmp called with b->x[b->wds-1] == 0");
9071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
9081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (i -= j)
9091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return i;
9101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	xa0 = a->x;
9111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	xa = xa0 + j;
9121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	xb0 = b->x;
9131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	xb = xb0 + j;
9141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	for(;;) {
9151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (*--xa != *--xb)
9161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return *xa < *xb ? -1 : 1;
9171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (xa <= xa0)
9181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
9191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
920e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	return 0;
921e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa}
9221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
9231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project static Bigint *
9241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectdiff
9251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef KR_headers
9261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(a, b) Bigint *a, *b;
9271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
9281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(Bigint *a, Bigint *b)
9291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
9301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
9311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	Bigint *c;
9321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int i, wa, wb;
9331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	Long borrow, y;	/* We need signed shifts here. */
9341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ULong *xa, *xae, *xb, *xbe, *xc;
9351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef Pack_32
9361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	Long z;
9371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
9381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
9398132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner	if (a == BIGINT_INVALID || b == BIGINT_INVALID)
9408132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		return BIGINT_INVALID;
9418132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner
9421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	i = cmp(a,b);
9431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (!i) {
9441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		c = Balloc(0);
9458132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		if (c != BIGINT_INVALID) {
9468132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner			c->wds = 1;
9478132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner			c->x[0] = 0;
9488132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner			}
9491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return c;
950e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
9511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (i < 0) {
9521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		c = a;
9531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		a = b;
9541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		b = c;
9551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		i = 1;
956e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
9571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	else
9581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		i = 0;
9591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	c = Balloc(a->k);
9608132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner	if (c == BIGINT_INVALID)
9618132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		return c;
9621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	c->sign = i;
9631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	wa = a->wds;
9641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	xa = a->x;
9651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	xae = xa + wa;
9661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	wb = b->wds;
9671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	xb = b->x;
9681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	xbe = xb + wb;
9691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	xc = c->x;
9701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	borrow = 0;
9711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef Pack_32
9721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	do {
9731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		y = (*xa & 0xffff) - (*xb & 0xffff) + borrow;
9741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		borrow = (ULong)y >> 16;
9751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		Sign_Extend(borrow, y);
9761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		z = (*xa++ >> 16) - (*xb++ >> 16) + borrow;
9771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		borrow = (ULong)z >> 16;
9781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		Sign_Extend(borrow, z);
9791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		Storeinc(xc, z, y);
980e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
981e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	while(xb < xbe);
9821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	while(xa < xae) {
9831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		y = (*xa & 0xffff) + borrow;
9841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		borrow = (ULong)y >> 16;
9851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		Sign_Extend(borrow, y);
9861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		z = (*xa++ >> 16) + borrow;
9871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		borrow = (ULong)z >> 16;
9881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		Sign_Extend(borrow, z);
9891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		Storeinc(xc, z, y);
990e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
9911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
9921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	do {
9931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		y = *xa++ - *xb++ + borrow;
9941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		borrow = y >> 16;
9951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		Sign_Extend(borrow, y);
9961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*xc++ = y & 0xffff;
997e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
998e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	while(xb < xbe);
9991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	while(xa < xae) {
10001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		y = *xa++ + borrow;
10011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		borrow = y >> 16;
10021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		Sign_Extend(borrow, y);
10031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*xc++ = y & 0xffff;
1004e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
10051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
10061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	while(!*--xc)
10071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		wa--;
10081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	c->wds = wa;
10091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return c;
1010e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa}
10111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
10121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project static double
10131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectulp
10141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef KR_headers
10151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(_x) double _x;
10161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
10171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(double _x)
10181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
10191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
10201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	_double x;
10211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	Long L;
10221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	_double a;
10231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
10241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	value(x) = _x;
10251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
10261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef Sudden_Underflow
10271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (L > 0) {
10281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
10291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef IBM
10301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		L |= Exp_msk1 >> 4;
10311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
10321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		word0(a) = L;
10331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		word1(a) = 0;
10341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef Sudden_Underflow
1035e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
10361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	else {
10371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		L = (ULong)-L >> Exp_shift;
10381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (L < Exp_shift) {
10391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			word0(a) = 0x80000 >> L;
10401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			word1(a) = 0;
1041e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
10421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		else {
10431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			word0(a) = 0;
10441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			L -= Exp_shift;
10451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			word1(a) = L >= 31 ? 1 : 1 << (31 - L);
10461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
1047e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
10481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
10491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return value(a);
1050e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa}
10511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
10521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project static double
10531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectb2d
10541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef KR_headers
10551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(a, e) Bigint *a; int *e;
10561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
10571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(Bigint *a, int *e)
10581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
10591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
10601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ULong *xa, *xa0, w, y, z;
10611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int k;
10621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	_double d;
10631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef VAX
10641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ULong d0, d1;
10651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
10661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define d0 word0(d)
10671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define d1 word1(d)
10681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
10691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
10708132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner	if (a == BIGINT_INVALID)
10718132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		return NAN;
10728132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner
10731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	xa0 = a->x;
10741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	xa = xa0 + a->wds;
10751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	y = *--xa;
10761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef DEBUG
10771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (!y) Bug("zero y in b2d");
10781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
10791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	k = hi0bits(y);
10801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*e = 32 - k;
10811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef Pack_32
10821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (k < Ebits) {
10831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		d0 = Exp_1 | y >> (Ebits - k);
10841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		w = xa > xa0 ? *--xa : 0;
10851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		d1 = y << ((32-Ebits) + k) | w >> (Ebits - k);
10861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		goto ret_d;
1087e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
10881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	z = xa > xa0 ? *--xa : 0;
10891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (k -= Ebits) {
10901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		d0 = Exp_1 | y << k | z >> (32 - k);
10911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		y = xa > xa0 ? *--xa : 0;
10921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		d1 = z << k | y >> (32 - k);
1093e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
10941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	else {
10951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		d0 = Exp_1 | y;
10961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		d1 = z;
1097e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
10981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
10991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (k < Ebits + 16) {
11001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		z = xa > xa0 ? *--xa : 0;
11011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
11021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		w = xa > xa0 ? *--xa : 0;
11031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		y = xa > xa0 ? *--xa : 0;
11041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
11051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		goto ret_d;
1106e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
11071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	z = xa > xa0 ? *--xa : 0;
11081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	w = xa > xa0 ? *--xa : 0;
11091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	k -= Ebits + 16;
11101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
11111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	y = xa > xa0 ? *--xa : 0;
11121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	d1 = w << k + 16 | y << k;
11131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
11141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ret_d:
11151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef VAX
11161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	word0(d) = d0 >> 16 | d0 << 16;
11171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	word1(d) = d1 >> 16 | d1 << 16;
11181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
11191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#undef d0
11201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#undef d1
11211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
11221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return value(d);
1123e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa}
11241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
11251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project static Bigint *
11261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectd2b
11271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef KR_headers
11281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(_d, e, bits) double d; int *e, *bits;
11291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
11301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(double _d, int *e, int *bits)
11311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
11321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
11331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	Bigint *b;
11341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int de, i, k;
11351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ULong *x, y, z;
11361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	_double d;
11371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef VAX
11381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ULong d0, d1;
11391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
11401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
11411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	value(d) = _d;
11421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef VAX
11431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	d0 = word0(d) >> 16 | word0(d) << 16;
11441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	d1 = word1(d) >> 16 | word1(d) << 16;
11451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
11461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define d0 word0(d)
11471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define d1 word1(d)
11481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
11491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
11501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef Pack_32
11511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	b = Balloc(1);
11521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
11531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	b = Balloc(2);
11541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
11558132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner	if (b == BIGINT_INVALID)
11568132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		return b;
11571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	x = b->x;
11581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
11591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	z = d0 & Frac_mask;
11601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	d0 &= 0x7fffffff;	/* clear sign bit, which we ignore */
11611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef Sudden_Underflow
11621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	de = (int)(d0 >> Exp_shift);
11631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef IBM
11641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	z |= Exp_msk11;
11651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
11661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
11671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if ((de = (int)(d0 >> Exp_shift)) != 0)
11681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		z |= Exp_msk1;
11691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
11701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef Pack_32
11711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if ((y = d1) != 0) {
11721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if ((k = lo0bits(&y)) != 0) {
11731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			x[0] = y | z << (32 - k);
11741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			z >>= k;
1175e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
11761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		else
11771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			x[0] = y;
11781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		i = b->wds = (x[1] = z) ? 2 : 1;
1179e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
11801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	else {
11811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef DEBUG
11821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (!z)
11831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			Bug("Zero passed to d2b");
11841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
11851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		k = lo0bits(&z);
11861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		x[0] = z;
11871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		i = b->wds = 1;
11881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		k += 32;
1189e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
11901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
11911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (y = d1) {
11921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (k = lo0bits(&y))
11931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (k >= 16) {
11941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				x[0] = y | z << 32 - k & 0xffff;
11951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				x[1] = z >> k - 16 & 0xffff;
11961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				x[2] = z >> k;
11971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				i = 2;
1198e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa			}
11991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else {
12001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				x[0] = y & 0xffff;
12011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				x[1] = y >> 16 | z << 16 - k & 0xffff;
12021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				x[2] = z >> k & 0xffff;
12031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				x[3] = z >> k+16;
12041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				i = 3;
1205e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa			}
12061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		else {
12071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			x[0] = y & 0xffff;
12081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			x[1] = y >> 16;
12091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			x[2] = z & 0xffff;
12101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			x[3] = z >> 16;
12111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			i = 3;
12121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
1213e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
12141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	else {
12151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef DEBUG
12161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (!z)
12171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			Bug("Zero passed to d2b");
12181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
12191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		k = lo0bits(&z);
12201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (k >= 16) {
12211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			x[0] = z;
12221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			i = 0;
1223e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
12241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		else {
12251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			x[0] = z & 0xffff;
12261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			x[1] = z >> 16;
12271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			i = 1;
12281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
1229e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		k += 32;
1230e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
12311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	while(!x[i])
12321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		--i;
12331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	b->wds = i + 1;
12341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
12351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef Sudden_Underflow
12361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (de) {
12371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
12381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef IBM
12391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*e = (de - Bias - (P-1) << 2) + k;
12401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);
12411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
12421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*e = de - Bias - (P-1) + k;
12431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*bits = P - k;
12441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
12451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef Sudden_Underflow
1246e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
12471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	else {
12481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*e = de - Bias - (P-1) + 1 + k;
12491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef Pack_32
12501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*bits = 32*i - hi0bits(x[i-1]);
12511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
12521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*bits = (i+2)*16 - hi0bits(x[i]);
12531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
12541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
12551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
12561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return b;
1257e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa}
12581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#undef d0
12591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#undef d1
12601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
12611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project static double
12621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectratio
12631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef KR_headers
12641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(a, b) Bigint *a, *b;
12651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
12661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(Bigint *a, Bigint *b)
12671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
12681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
12691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	_double da, db;
12701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int k, ka, kb;
12711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
12728132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner	if (a == BIGINT_INVALID || b == BIGINT_INVALID)
12738132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		return NAN; /* for lack of better value ? */
12748132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner
12751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	value(da) = b2d(a, &ka);
12761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	value(db) = b2d(b, &kb);
12771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef Pack_32
12781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	k = ka - kb + 32*(a->wds - b->wds);
12791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
12801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	k = ka - kb + 16*(a->wds - b->wds);
12811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
12821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef IBM
12831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (k > 0) {
12841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		word0(da) += (k >> 2)*Exp_msk1;
12851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (k &= 3)
12861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			da *= 1 << k;
1287e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
12881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	else {
12891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		k = -k;
12901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		word0(db) += (k >> 2)*Exp_msk1;
12911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (k &= 3)
12921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			db *= 1 << k;
1293e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
12941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
12951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (k > 0)
12961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		word0(da) += k*Exp_msk1;
12971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	else {
12981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		k = -k;
12991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		word0(db) += k*Exp_msk1;
1300e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
13011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
13021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return value(da) / value(db);
1303e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa}
13041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
13051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic CONST double
13061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projecttens[] = {
13071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
13081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
13091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		1e20, 1e21, 1e22
13101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef VAX
13111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		, 1e23, 1e24
13121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1313e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa};
13141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
13151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef IEEE_Arith
13161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic CONST double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
13171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 };
13181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define n_bigtens 5
13191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
13201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef IBM
13211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic CONST double bigtens[] = { 1e16, 1e32, 1e64 };
13221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 };
13231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define n_bigtens 3
13241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
13251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic CONST double bigtens[] = { 1e16, 1e32 };
13261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic CONST double tinytens[] = { 1e-16, 1e-32 };
13271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define n_bigtens 2
13281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
13291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
13301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
13311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project double
13321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstrtod
13331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef KR_headers
13341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(s00, se) CONST char *s00; char **se;
13351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
13361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(CONST char *s00, char **se)
13371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
13381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
13391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
13401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
13411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	CONST char *s, *s0, *s1;
13421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	double aadj, aadj1, adj;
13431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	_double rv, rv0;
13441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	Long L;
13451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ULong y, z;
13461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	Bigint *bb1, *bd0;
13471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	Bigint *bb = NULL, *bd = NULL, *bs = NULL, *delta = NULL;/* pacify gcc */
13481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
13491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef ANDROID_CHANGES
13501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	CONST char decimal_point = '.';
13511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else /* ANDROID_CHANGES */
13521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef KR_headers
13531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	CONST char decimal_point = localeconv()->decimal_point[0];
13541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
13551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	CONST char decimal_point = '.';
13561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
13571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
13581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* ANDROID_CHANGES */
13591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
13601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	sign = nz0 = nz = 0;
13611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	value(rv) = 0.;
13621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
13631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
13641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	for(s = s00; isspace((unsigned char) *s); s++)
13651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		;
13661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
13671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (*s == '-') {
13681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		sign = 1;
13691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		s++;
13701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	} else if (*s == '+') {
13711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		s++;
13721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
13731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
13741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (*s == '\0') {
13751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		s = s00;
13761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		goto ret;
13771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
13781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
13791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* "INF" or "INFINITY" */
13801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (tolower((unsigned char)*s) == 'i' && strncasecmp(s, "inf", 3) == 0) {
13811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (strncasecmp(s + 3, "inity", 5) == 0)
13821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			s += 8;
13831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		else
13841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			s += 3;
13851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
13861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		value(rv) = HUGE_VAL;
13871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		goto ret;
13881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
13891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
13901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef IEEE_Arith
13911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* "NAN" or "NAN(n-char-sequence-opt)" */
13921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (tolower((unsigned char)*s) == 'n' && strncasecmp(s, "nan", 3) == 0) {
13931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/* Build a quiet NaN. */
13941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		word0(rv) = NAN_WORD0;
13951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		word1(rv) = NAN_WORD1;
13961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		s+= 3;
13971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
13981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/* Don't interpret (n-char-sequence-opt), for now. */
13991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (*s == '(') {
14001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			s0 = s;
14011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			for (s++; *s != ')' && *s != '\0'; s++)
14021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				;
14031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (*s == ')')
14041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				s++;	/* Skip over closing paren ... */
14051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else
14061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				s = s0;	/* ... otherwise go back. */
14071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
14081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
14091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		goto ret;
14101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
14111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
14121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
14131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (*s == '0') {
14141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		nz0 = 1;
14151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		while(*++s == '0') ;
14161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (!*s)
14171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto ret;
1418e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
14191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	s0 = s;
14201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	y = z = 0;
14211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
14221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (nd < 9)
14231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			y = 10*y + c - '0';
14241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		else if (nd < 16)
14251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			z = 10*z + c - '0';
14261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	nd0 = nd;
14271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (c == decimal_point) {
14281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		c = *++s;
14291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (!nd) {
14301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			for(; c == '0'; c = *++s)
14311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				nz++;
14321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (c > '0' && c <= '9') {
14331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				s0 = s;
14341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				nf += nz;
14351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				nz = 0;
14361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				goto have_dig;
14371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				}
14381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto dig_done;
1439e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
14401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		for(; c >= '0' && c <= '9'; c = *++s) {
14411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project have_dig:
14421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			nz++;
14431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (c -= '0') {
14441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				nf += nz;
14451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				for(i = 1; i < nz; i++)
14461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					if (nd++ < 9)
14471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						y *= 10;
14481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					else if (nd <= DBL_DIG + 1)
14491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						z *= 10;
14501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (nd++ < 9)
14511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					y = 10*y + c;
14521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				else if (nd <= DBL_DIG + 1)
14531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					z = 10*z + c;
14541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				nz = 0;
14551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
14561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
1457e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
14581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project dig_done:
14591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	e = 0;
14601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (c == 'e' || c == 'E') {
14611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (!nd && !nz && !nz0) {
14621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			s = s00;
14631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto ret;
1464e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
14651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		s00 = s;
14661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		esign = 0;
14671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		switch(c = *++s) {
14681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			case '-':
14691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				esign = 1;
14701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/* FALLTHROUGH */
14711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			case '+':
14721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				c = *++s;
1473e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
14741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (c >= '0' && c <= '9') {
14751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			while(c == '0')
14761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				c = *++s;
14771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (c > '0' && c <= '9') {
14781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				L = c - '0';
14791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				s1 = s;
14801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				while((c = *++s) >= '0' && c <= '9')
14811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					L = 10*L + c - '0';
14821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (s - s1 > 8 || L > 19999)
14831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					/* Avoid confusion from exponents
14841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					 * so large that e might overflow.
14851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					 */
14861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					e = 19999; /* safe for 16 bit ints */
14871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				else
14881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					e = (int)L;
14891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (esign)
14901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					e = -e;
1491e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa			}
14921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else
14931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				e = 0;
1494e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
14951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		else
14961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			s = s00;
1497e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
14981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (!nd) {
14991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (!nz && !nz0)
15001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			s = s00;
15011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		goto ret;
1502e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
15031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	e1 = e -= nf;
15041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
15051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* Now we have nd0 digits, starting at s0, followed by a
15061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * decimal point, followed by nd-nd0 digits.  The number we're
15071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * after is the integer represented by those digits times
15081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * 10**e */
15091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
15101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (!nd0)
15111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		nd0 = nd;
15121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
15131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	value(rv) = y;
15141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (k > 9)
15151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		value(rv) = tens[k - 9] * value(rv) + z;
15161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	bd0 = 0;
15171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (nd <= DBL_DIG
15181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef RND_PRODQUOT
15191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		&& FLT_ROUNDS == 1
15201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1521e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		) {
15221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (!e)
15231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto ret;
15241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (e > 0) {
15251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (e <= Ten_pmax) {
15261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef VAX
15271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				goto vax_ovfl_check;
15281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
15291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/* value(rv) = */ rounded_product(value(rv),
15301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				    tens[e]);
15311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				goto ret;
15321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1533e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa			}
15341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			i = DBL_DIG - nd;
15351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (e <= Ten_pmax + i) {
15361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/* A fancier test would sometimes let us do
15371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * this for larger i values.
15381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 */
15391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				e -= i;
15401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				value(rv) *= tens[i];
15411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef VAX
15421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/* VAX exponent range is so narrow we must
15431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * worry about overflow here...
15441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 */
15451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project vax_ovfl_check:
15461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				word0(rv) -= P*Exp_msk1;
15471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/* value(rv) = */ rounded_product(value(rv),
15481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				    tens[e]);
15491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if ((word0(rv) & Exp_mask)
15501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
15511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					goto ovfl;
15521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				word0(rv) += P*Exp_msk1;
15531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
15541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/* value(rv) = */ rounded_product(value(rv),
15551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				    tens[e]);
15561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
15571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				goto ret;
15581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
1559e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
15601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef Inaccurate_Divide
15611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		else if (e >= -Ten_pmax) {
15621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* value(rv) = */ rounded_quotient(value(rv),
15631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			    tens[-e]);
15641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto ret;
15651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
1566e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa#endif
1567e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
15681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	e1 += nd - k;
15691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
15701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* Get starting approximation = rv * 10**e1 */
15711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
15721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (e1 > 0) {
15731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if ((i = e1 & 15) != 0)
15741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			value(rv) *= tens[i];
15751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (e1 &= ~15) {
15761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (e1 > DBL_MAX_10_EXP) {
15771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ovfl:
15781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				errno = ERANGE;
15791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				value(rv) = HUGE_VAL;
15801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (bd0)
15811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					goto retfree;
15821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				goto ret;
1583e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa			}
15841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if ((e1 = (unsigned int)e1 >> 4) != 0) {
15851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				for(j = 0; e1 > 1; j++,
15861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				    e1 = (unsigned int)e1 >> 1)
15871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					if (e1 & 1)
15881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						value(rv) *= bigtens[j];
15891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* The last multiplication could overflow. */
15901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				word0(rv) -= P*Exp_msk1;
15911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				value(rv) *= bigtens[j];
15921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if ((z = word0(rv) & Exp_mask)
15931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 > Exp_msk1*(DBL_MAX_EXP+Bias-P))
15941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					goto ovfl;
15951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
15961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					/* set to largest number */
15971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					/* (Can't trust DBL_MAX) */
15981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					word0(rv) = Big0;
15991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					word1(rv) = Big1;
16001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					}
16011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				else
16021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					word0(rv) += P*Exp_msk1;
16031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
16041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
1605e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
16061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	else if (e1 < 0) {
16071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		e1 = -e1;
16081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if ((i = e1 & 15) != 0)
16091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			value(rv) /= tens[i];
16101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (e1 &= ~15) {
16111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			e1 = (unsigned int)e1 >> 4;
16121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (e1 >= 1 << n_bigtens)
16131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				goto undfl;
16141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			for(j = 0; e1 > 1; j++,
16151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			    e1 = (unsigned int)e1 >> 1)
16161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (e1 & 1)
16171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					value(rv) *= tinytens[j];
16181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* The last multiplication could underflow. */
16191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			value(rv0) = value(rv);
16201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			value(rv) *= tinytens[j];
16211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (!value(rv)) {
16221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				value(rv) = 2.*value(rv0);
16231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				value(rv) *= tinytens[j];
16241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (!value(rv)) {
16251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project undfl:
16261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					value(rv) = 0.;
16271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					errno = ERANGE;
16281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					if (bd0)
16291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						goto retfree;
16301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					goto ret;
1631e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa				}
16321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				word0(rv) = Tiny0;
16331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				word1(rv) = Tiny1;
16341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/* The refinement below will clean
16351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * this approximation up.
16361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 */
16371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
16381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
1639e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
16401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
16411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* Now the hard part -- adjusting rv to the correct value.*/
16421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
16431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* Put digits into bd: true value = bd * 10^e */
16441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
16451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	bd0 = s2b(s0, nd0, nd, y);
16461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
16471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	for(;;) {
16481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		bd = Balloc(bd0->k);
16491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		Bcopy(bd, bd0);
16501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		bb = d2b(value(rv), &bbe, &bbbits);	/* rv = bb * 2^bbe */
16511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		bs = i2b(1);
16521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
16531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (e >= 0) {
16541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			bb2 = bb5 = 0;
16551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			bd2 = bd5 = e;
1656e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
16571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		else {
16581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			bb2 = bb5 = -e;
16591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			bd2 = bd5 = 0;
1660e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
16611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (bbe >= 0)
16621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			bb2 += bbe;
16631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		else
16641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			bd2 -= bbe;
16651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		bs2 = bb2;
16661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef Sudden_Underflow
16671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef IBM
16681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
16691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
16701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		j = P + 1 - bbbits;
16711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
16721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
16731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		i = bbe + bbbits - 1;	/* logb(rv) */
16741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (i < Emin)	/* denormal */
16751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			j = bbe + (P-Emin);
16761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		else
16771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			j = P + 1 - bbbits;
16781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
16791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		bb2 += j;
16801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		bd2 += j;
16811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		i = bb2 < bd2 ? bb2 : bd2;
16821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (i > bs2)
16831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			i = bs2;
16841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (i > 0) {
16851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			bb2 -= i;
16861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			bd2 -= i;
16871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			bs2 -= i;
1688e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
16891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (bb5 > 0) {
16901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			bs = pow5mult(bs, bb5);
16911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			bb1 = mult(bs, bb);
16921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			Bfree(bb);
16931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			bb = bb1;
1694e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
16951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (bb2 > 0)
16961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			bb = lshift(bb, bb2);
16971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (bd5 > 0)
16981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			bd = pow5mult(bd, bd5);
16991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (bd2 > 0)
17001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			bd = lshift(bd, bd2);
17011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (bs2 > 0)
17021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			bs = lshift(bs, bs2);
17031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		delta = diff(bb, bd);
17041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		dsign = delta->sign;
17051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		delta->sign = 0;
17061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		i = cmp(delta, bs);
17071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (i < 0) {
17081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* Error is less than half an ulp -- check for
17091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * special case of mantissa a power of two.
17101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 */
17111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (dsign || word1(rv) || word0(rv) & Bndry_mask)
17121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				break;
17131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			delta = lshift(delta,Log2P);
17141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (cmp(delta, bs) > 0)
17151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				goto drop_down;
17161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
1717e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
17181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (i == 0) {
17191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* exactly half-way between */
17201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (dsign) {
17211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if ((word0(rv) & Bndry_mask1) == Bndry_mask1
17221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 &&  word1(rv) == 0xffffffff) {
17231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					/*boundary case -- increment exponent*/
17241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					word0(rv) = (word0(rv) & Exp_mask)
17251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						+ Exp_msk1
17261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef IBM
17271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						| Exp_msk1 >> 4
17281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
17291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						;
17301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					word1(rv) = 0;
17311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					break;
17321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				}
1733e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa			}
17341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else if (!(word0(rv) & Bndry_mask) && !word1(rv)) {
17351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project drop_down:
17361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/* boundary case -- decrement exponent */
17371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef Sudden_Underflow
17381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				L = word0(rv) & Exp_mask;
17391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef IBM
17401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (L <  Exp_msk1)
17411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
17421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (L <= Exp_msk1)
17431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
17441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					goto undfl;
17451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				L -= Exp_msk1;
17461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
17471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				L = (word0(rv) & Exp_mask) - Exp_msk1;
17481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
17491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				word0(rv) = L | Bndry_mask1;
17501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				word1(rv) = 0xffffffff;
17511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef IBM
17521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				goto cont;
17531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
17541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				break;
17551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1756e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa			}
17571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef ROUND_BIASED
17581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (!(word1(rv) & LSB))
17591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				break;
17601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
17611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (dsign)
17621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				value(rv) += ulp(value(rv));
17631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef ROUND_BIASED
17641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else {
17651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				value(rv) -= ulp(value(rv));
17661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef Sudden_Underflow
17671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (!value(rv))
17681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					goto undfl;
17691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1770e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa			}
17711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
17721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
1773e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
17741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if ((aadj = ratio(delta, bs)) <= 2.) {
17751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (dsign)
17761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				aadj = aadj1 = 1.;
17771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else if (word1(rv) || word0(rv) & Bndry_mask) {
17781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef Sudden_Underflow
17791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (word1(rv) == Tiny1 && !word0(rv))
17801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					goto undfl;
17811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
17821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				aadj = 1.;
17831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				aadj1 = -1.;
1784e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa			}
17851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else {
17861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/* special case -- power of FLT_RADIX to be */
17871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/* rounded down... */
17881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
17891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (aadj < 2./FLT_RADIX)
17901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					aadj = 1./FLT_RADIX;
17911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				else
17921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					aadj *= 0.5;
17931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				aadj1 = -aadj;
17941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				}
1795e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
17961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		else {
17971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			aadj *= 0.5;
17981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			aadj1 = dsign ? aadj : -aadj;
17991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef Check_FLT_ROUNDS
18001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			switch(FLT_ROUNDS) {
18011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				case 2: /* towards +infinity */
18021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					aadj1 -= 0.5;
18031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					break;
18041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				case 0: /* towards 0 */
18051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				case 3: /* towards -infinity */
18061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					aadj1 += 0.5;
1807e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa			}
18081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
18091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (FLT_ROUNDS == 0)
18101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				aadj1 += 0.5;
18111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1812e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
18131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		y = word0(rv) & Exp_mask;
18141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
18151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/* Check for overflow */
18161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
18171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
18181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			value(rv0) = value(rv);
18191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			word0(rv) -= P*Exp_msk1;
18201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			adj = aadj1 * ulp(value(rv));
18211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			value(rv) += adj;
18221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if ((word0(rv) & Exp_mask) >=
18231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
18241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (word0(rv0) == Big0 && word1(rv0) == Big1)
18251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					goto ovfl;
18261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				word0(rv) = Big0;
18271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				word1(rv) = Big1;
18281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				goto cont;
1829e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa			}
18301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else
18311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				word0(rv) += P*Exp_msk1;
1832e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
18331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		else {
18341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef Sudden_Underflow
18351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
18361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				value(rv0) = value(rv);
18371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				word0(rv) += P*Exp_msk1;
18381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				adj = aadj1 * ulp(value(rv));
18391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				value(rv) += adj;
18401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef IBM
18411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if ((word0(rv) & Exp_mask) <  P*Exp_msk1)
18421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
18431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if ((word0(rv) & Exp_mask) <= P*Exp_msk1)
18441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1845e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa				{
18461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					if (word0(rv0) == Tiny0
18471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					 && word1(rv0) == Tiny1)
18481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						goto undfl;
18491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					word0(rv) = Tiny0;
18501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					word1(rv) = Tiny1;
18511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					goto cont;
1852e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa				}
18531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				else
18541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					word0(rv) -= P*Exp_msk1;
18551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				}
18561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else {
18571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				adj = aadj1 * ulp(value(rv));
18581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				value(rv) += adj;
1859e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa			}
18601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
18611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* Compute adj so that the IEEE rounding rules will
18621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * correctly round rv + adj in some half-way cases.
18631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * If rv * ulp(rv) is denormalized (i.e.,
18641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
18651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * trouble from bits lost to denormalization;
18661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * example: 1.2e-307 .
18671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 */
18681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (y <= (P-1)*Exp_msk1 && aadj >= 1.) {
18691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				aadj1 = (double)(int)(aadj + 0.5);
18701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (!dsign)
18711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					aadj1 = -aadj1;
1872e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa			}
18731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			adj = aadj1 * ulp(value(rv));
18741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			value(rv) += adj;
18751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1876e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
18771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		z = word0(rv) & Exp_mask;
18781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (y == z) {
18791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* Can we stop now? */
18801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			L = aadj;
18811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			aadj -= L;
18821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* The tolerances below are conservative. */
18831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (dsign || word1(rv) || word0(rv) & Bndry_mask) {
18841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (aadj < .4999999 || aadj > .5000001)
18851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					break;
1886e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa			}
18871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else if (aadj < .4999999/FLT_RADIX)
18881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				break;
1889e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
18901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cont:
18911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		Bfree(bb);
18921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		Bfree(bd);
18931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		Bfree(bs);
18941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		Bfree(delta);
1895e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
18961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project retfree:
18971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	Bfree(bb);
18981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	Bfree(bd);
18991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	Bfree(bs);
19001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	Bfree(bd0);
19011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	Bfree(delta);
19021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ret:
19031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (se)
19041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/* LINTED interface specification */
19051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*se = (char *)s;
19061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return sign ? -value(rv) : value(rv);
1907e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa}
19081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
19091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project static int
19101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectquorem
19111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef KR_headers
19121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(b, S) Bigint *b, *S;
19131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
19141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(Bigint *b, Bigint *S)
19151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
19161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
19171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int n;
19181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	Long borrow, y;
19191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ULong carry, q, ys;
19201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ULong *bx, *bxe, *sx, *sxe;
19211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef Pack_32
19221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	Long z;
19231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ULong si, zs;
19241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
19251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
19268132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner	if (b == BIGINT_INVALID || S == BIGINT_INVALID)
19278132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		return 0;
19288132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner
19291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	n = S->wds;
19301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef DEBUG
19311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/*debug*/ if (b->wds > n)
19321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/*debug*/	Bug("oversize b in quorem");
19331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
19341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (b->wds < n)
19351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return 0;
19361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	sx = S->x;
19371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	sxe = sx + --n;
19381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	bx = b->x;
19391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	bxe = bx + n;
19401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	q = *bxe / (*sxe + 1);	/* ensure q <= true quotient */
19411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef DEBUG
19421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/*debug*/ if (q > 9)
19431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/*debug*/	Bug("oversized quotient in quorem");
19441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
19451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (q) {
19461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		borrow = 0;
19471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		carry = 0;
19481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		do {
19491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef Pack_32
19501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			si = *sx++;
19511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ys = (si & 0xffff) * q + carry;
19521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			zs = (si >> 16) * q + (ys >> 16);
19531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			carry = zs >> 16;
19541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
19551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			borrow = (ULong)y >> 16;
19561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			Sign_Extend(borrow, y);
19571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			z = (*bx >> 16) - (zs & 0xffff) + borrow;
19581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			borrow = (ULong)z >> 16;
19591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			Sign_Extend(borrow, z);
19601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			Storeinc(bx, z, y);
19611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
19621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ys = *sx++ * q + carry;
19631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			carry = ys >> 16;
19641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			y = *bx - (ys & 0xffff) + borrow;
19651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			borrow = y >> 16;
19661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			Sign_Extend(borrow, y);
19671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			*bx++ = y & 0xffff;
19681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1969e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
1970e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		while(sx <= sxe);
19711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (!*bxe) {
19721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			bx = b->x;
19731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			while(--bxe > bx && !*bxe)
19741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				--n;
19751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			b->wds = n;
19761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
1977e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
19781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (cmp(b, S) >= 0) {
19791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		q++;
19801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		borrow = 0;
19811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		carry = 0;
19821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		bx = b->x;
19831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		sx = S->x;
19841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		do {
19851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef Pack_32
19861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			si = *sx++;
19871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ys = (si & 0xffff) + carry;
19881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			zs = (si >> 16) + (ys >> 16);
19891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			carry = zs >> 16;
19901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
19911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			borrow = (ULong)y >> 16;
19921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			Sign_Extend(borrow, y);
19931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			z = (*bx >> 16) - (zs & 0xffff) + borrow;
19941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			borrow = (ULong)z >> 16;
19951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			Sign_Extend(borrow, z);
19961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			Storeinc(bx, z, y);
19971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
19981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ys = *sx++ + carry;
19991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			carry = ys >> 16;
20001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			y = *bx - (ys & 0xffff) + borrow;
20011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			borrow = y >> 16;
20021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			Sign_Extend(borrow, y);
20031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			*bx++ = y & 0xffff;
20041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
2005e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
2006e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		while(sx <= sxe);
20071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		bx = b->x;
20081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		bxe = bx + n;
20091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (!*bxe) {
20101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			while(--bxe > bx && !*bxe)
20111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				--n;
20121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			b->wds = n;
20131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
20141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
2015e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	return q;
2016e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa}
20171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
20181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* freedtoa(s) must be used to free values s returned by dtoa
20191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * when MULTIPLE_THREADS is #defined.  It should be used in all cases,
20201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * but for consistency with earlier versions of dtoa, it is optional
20211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * when MULTIPLE_THREADS is not defined.
20221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
20231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
20241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectvoid
20251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef KR_headers
20261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectfreedtoa(s) char *s;
20271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
20281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectfreedtoa(char *s)
20291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
20301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
20311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	free(s);
20321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
20331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
20341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
20351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
20361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
20371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
20381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Inspired by "How to Print Floating-Point Numbers Accurately" by
20391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
20401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
20411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Modifications:
20421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	1. Rather than iterating, we use a simple numeric overestimate
20431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	   to determine k = floor(log10(d)).  We scale relevant
20441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	   quantities using O(log2(k)) rather than O(k) multiplications.
20451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
20461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	   try to generate digits strictly left to right.  Instead, we
20471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	   compute with fewer bits and propagate the carry if necessary
20481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	   when rounding the final digit up.  This is often faster.
20491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	3. Under the assumption that input will be rounded nearest,
20501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	   mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
20511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	   That is, we allow equality in stopping tests when the
20521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	   round-nearest rule will give the same floating-point value
20531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	   as would satisfaction of the stopping test with strict
20541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	   inequality.
20551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	4. We remove common factors of powers of 2 from relevant
20561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	   quantities.
20571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	5. When converting floating-point integers less than 1e16,
20581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	   we use floating-point arithmetic rather than resorting
20591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	   to multiple-precision integers.
20601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	6. When asked to produce fewer than 15 digits, we first try
20611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	   to get by with floating-point arithmetic; we resort to
20621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	   multiple-precision integer arithmetic only if we cannot
20631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	   guarantee that the floating-point calculation has given
20641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	   the correctly rounded result.  For k requested digits and
20651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	   "uniformly" distributed input, the probability is
20661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	   something like 10^(k-15) that we must resort to the Long
20671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	   calculation.
20681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
20691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2070cec75a765fbadc49668b0f72d885233cc95a0db7Jim Huang__LIBC_HIDDEN__  char *
20711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project__dtoa
20721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef KR_headers
20731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(_d, mode, ndigits, decpt, sign, rve)
20741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	double _d; int mode, ndigits, *decpt, *sign; char **rve;
20751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
20761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(double _d, int mode, int ndigits, int *decpt, int *sign, char **rve)
20771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
20781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
20791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /*	Arguments ndigits, decpt, sign are similar to those
20801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	of ecvt and fcvt; trailing zeros are suppressed from
20811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	the returned string.  If not null, *rve is set to point
20821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	to the end of the return value.  If d is +-Infinity or NaN,
20831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	then *decpt is set to 9999.
20841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
20851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	mode:
20861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		0 ==> shortest string that yields d when read in
20871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			and rounded to nearest.
20881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		1 ==> like 0, but with Steele & White stopping rule;
20891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			e.g. with IEEE P754 arithmetic , mode 0 gives
20901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			1e23 whereas mode 1 gives 9.999999999999999e22.
20911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		2 ==> max(1,ndigits) significant digits.  This gives a
20921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return value similar to that of ecvt, except
20931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			that trailing zeros are suppressed.
20941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		3 ==> through ndigits past the decimal point.  This
20951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			gives a return value similar to that from fcvt,
20961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			except that trailing zeros are suppressed, and
20971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ndigits can be negative.
20981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		4-9 should give the same return values as 2-3, i.e.,
20991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			4 <= mode <= 9 ==> same return as mode
21001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			2 + (mode & 1).  These modes are mainly for
21011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			debugging; often they run slower but sometimes
21021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			faster than modes 2-3.
21031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		4,5,8,9 ==> left-to-right digit generation.
21041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		6-9 ==> don't try fast floating-point estimate
21051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			(if applicable).
21061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
21071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		Values of mode other than 0-9 are treated as mode 0.
21081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
21091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		Sufficient space is allocated to the return value
21101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		to hold the suppressed trailing zeros.
21111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*/
21121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
21131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int bbits, b2, b5, be, dig, i, ieps, ilim0,
21141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		j, jj1, k, k0, k_check, leftright, m2, m5, s2, s5,
21151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		try_quick;
21161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int ilim = 0, ilim1 = 0, spec_case = 0;	/* pacify gcc */
21171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	Long L;
21181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef Sudden_Underflow
21191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int denorm;
21201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ULong x;
21211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
21221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	Bigint *b, *b1, *delta, *mhi, *S;
21231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	Bigint *mlo = NULL; /* pacify gcc */
21241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	double ds;
21251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char *s, *s0;
21261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	Bigint *result = NULL;
21271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int result_k = 0;
21281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	_double d, d2, eps;
21291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
21301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	value(d) = _d;
21311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
21321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (word0(d) & Sign_bit) {
21331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/* set sign for everything, including 0's and NaNs */
21341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*sign = 1;
21351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		word0(d) &= ~Sign_bit;	/* clear sign bit */
2136e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
21371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	else
21381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*sign = 0;
21391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
21401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if defined(IEEE_Arith) + defined(VAX)
21411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef IEEE_Arith
21421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if ((word0(d) & Exp_mask) == Exp_mask)
21431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
21441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (word0(d)  == 0x8000)
21451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
2146e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	{
21471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/* Infinity or NaN */
21481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*decpt = 9999;
21491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		s =
21501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef IEEE_Arith
21511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			!word1(d) && !(word0(d) & 0xfffff) ? "Infinity" :
21521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
21531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				"NaN";
21548132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		result = Balloc(strlen(s)+1);
21558132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		if (result == BIGINT_INVALID)
21568132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner			return NULL;
21578132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		s0 = (char *)(void *)result;
21588132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		strcpy(s0, s);
21598132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		if (rve)
21608132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner			*rve =
21611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef IEEE_Arith
21628132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner				s0[3] ? s0 + 8 :
21631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
21648132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner				s0 + 3;
21651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return s0;
2166e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
21671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
21681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef IBM
21691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	value(d) += 0; /* normalize */
21701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
21711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (!value(d)) {
21721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*decpt = 1;
21738132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		result = Balloc(2);
21748132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		if (result == BIGINT_INVALID)
21758132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner			return NULL;
2176e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		s0 = (char *)(void *)result;
2177e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		strcpy(s0, "0");
2178e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		if (rve)
21798132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner			*rve = s0 + 1;
2180e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		return s0;
2181e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
21821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
21831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	b = d2b(value(d), &be, &bbits);
21841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef Sudden_Underflow
21851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
21861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
21871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if ((i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) {
21881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
21891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		value(d2) = value(d);
21901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		word0(d2) &= Frac_mask1;
21911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		word0(d2) |= Exp_11;
21921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef IBM
21931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (j = 11 - hi0bits(word0(d2) & Frac_mask))
21941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			value(d2) /= 1 << j;
21951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
21961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
21971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/* log(x)	~=~ log(1.5) + (x-1.5)/1.5
21981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * log10(x)	 =  log(x) / log(10)
21991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 *		~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
22001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
22011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 *
22021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * This suggests computing an approximation k to log10(d) by
22031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 *
22041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * k = (i - Bias)*0.301029995663981
22051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 *	+ ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
22061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 *
22071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * We want k to be too large rather than too small.
22081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * The error in the first-order Taylor series approximation
22091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * is in our favor, so we just round up the constant enough
22101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * to compensate for any error in the multiplication of
22111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
22121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
22131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * adding 1e-13 to the constant term more than suffices.
22141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * Hence we adjust the constant term to 0.1760912590558.
22151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * (We could get a more accurate k by invoking log10,
22161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 *  but this is probably not worthwhile.)
22171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 */
22181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
22191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		i -= Bias;
22201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef IBM
22211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		i <<= 2;
22221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		i += j;
22231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
22241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef Sudden_Underflow
22251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		denorm = 0;
2226e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
22271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	else {
22281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/* d is denormalized */
22291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
22301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		i = bbits + be + (Bias + (P-1) - 1);
22311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		x = i > 32  ? word0(d) << (64 - i) | word1(d) >> (i - 32)
22321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			    : word1(d) << (32 - i);
22331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		value(d2) = x;
22341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		word0(d2) -= 31*Exp_msk1; /* adjust exponent */
22351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		i -= (Bias + (P-1) - 1) + 1;
22361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		denorm = 1;
2237e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
22381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
22391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ds = (value(d2)-1.5)*0.289529654602168 + 0.1760912590558 +
22401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    i*0.301029995663981;
22411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	k = (int)ds;
22421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (ds < 0. && ds != k)
22431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		k--;	/* want k = floor(ds) */
22441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	k_check = 1;
22451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (k >= 0 && k <= Ten_pmax) {
22461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (value(d) < tens[k])
22471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			k--;
22481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		k_check = 0;
2249e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
22501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	j = bbits - i - 1;
22511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (j >= 0) {
22521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		b2 = 0;
22531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		s2 = j;
2254e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
22551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	else {
22561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		b2 = -j;
22571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		s2 = 0;
2258e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
22591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (k >= 0) {
22601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		b5 = 0;
22611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		s5 = k;
22621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		s2 += k;
2263e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
22641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	else {
22651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		b2 -= k;
22661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		b5 = -k;
22671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		s5 = 0;
2268e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
22691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (mode < 0 || mode > 9)
22701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		mode = 0;
22711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	try_quick = 1;
22721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (mode > 5) {
22731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		mode -= 4;
22741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		try_quick = 0;
2275e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
22761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	leftright = 1;
22771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	switch(mode) {
22781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 0:
22791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 1:
22801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ilim = ilim1 = -1;
22811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			i = 18;
22821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ndigits = 0;
22831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
22841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 2:
22851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			leftright = 0;
22861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* FALLTHROUGH */
22871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 4:
22881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (ndigits <= 0)
22891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				ndigits = 1;
22901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ilim = ilim1 = i = ndigits;
22911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
22921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 3:
22931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			leftright = 0;
22941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* FALLTHROUGH */
22951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 5:
22961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			i = ndigits + k + 1;
22971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ilim = i;
22981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ilim1 = i - 1;
22991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (i <= 0)
23001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				i = 1;
2301e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
23021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	j = sizeof(ULong);
23031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        for(result_k = 0; (int)(sizeof(Bigint) - sizeof(ULong)) + j <= i;
23041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		j <<= 1) result_k++;
23051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        // this is really a ugly hack, the code uses Balloc
23061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        // instead of malloc, but casts the result into a char*
23071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        // it seems the only reason to do that is due to the
23081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        // complicated way the block size need to be computed
23091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        // buuurk....
23101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	result = Balloc(result_k);
23118132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner	if (result == BIGINT_INVALID) {
23128132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		Bfree(b);
23138132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		return NULL;
23148132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner	}
23151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	s = s0 = (char *)(void *)result;
23161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
23171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (ilim >= 0 && ilim <= Quick_max && try_quick) {
23181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
23191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/* Try to get by with floating-point arithmetic. */
23201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
23211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		i = 0;
23221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		value(d2) = value(d);
23231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		k0 = k;
23241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		ilim0 = ilim;
23251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		ieps = 2; /* conservative */
23261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (k > 0) {
23271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ds = tens[k&0xf];
23281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			j = (unsigned int)k >> 4;
23291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (j & Bletch) {
23301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/* prevent overflows */
23311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				j &= Bletch - 1;
23321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				value(d) /= bigtens[n_bigtens-1];
23331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				ieps++;
23341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				}
23351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			for(; j; j = (unsigned int)j >> 1, i++)
23361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (j & 1) {
23371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					ieps++;
23381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					ds *= bigtens[i];
23391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					}
23401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			value(d) /= ds;
2341e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
23421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		else if ((jj1 = -k) != 0) {
23431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			value(d) *= tens[jj1 & 0xf];
23441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			for(j = (unsigned int)jj1 >> 4; j;
23451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			    j = (unsigned int)j >> 1, i++)
23461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (j & 1) {
23471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					ieps++;
23481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					value(d) *= bigtens[i];
2349e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa				}
2350e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
23511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (k_check && value(d) < 1. && ilim > 0) {
23521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (ilim1 <= 0)
23531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				goto fast_failed;
23541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ilim = ilim1;
23551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			k--;
23561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			value(d) *= 10.;
23571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ieps++;
2358e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
23591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		value(eps) = ieps*value(d) + 7.;
23601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		word0(eps) -= (P-1)*Exp_msk1;
23611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (ilim == 0) {
23621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			S = mhi = 0;
23631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			value(d) -= 5.;
23641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (value(d) > value(eps))
23651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				goto one_digit;
23661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (value(d) < -value(eps))
23671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				goto no_digits;
23681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto fast_failed;
2369e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
23701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef No_leftright
23711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (leftright) {
23721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* Use Steele & White method of only
23731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * generating digits needed.
23741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 */
23751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			value(eps) = 0.5/tens[ilim-1] - value(eps);
23761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			for(i = 0;;) {
23771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				L = value(d);
23781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				value(d) -= L;
23791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*s++ = '0' + (int)L;
23801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (value(d) < value(eps))
23811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					goto ret1;
23821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (1. - value(d) < value(eps))
23831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					goto bump_up;
23841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (++i >= ilim)
23851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					break;
23861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				value(eps) *= 10.;
23871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				value(d) *= 10.;
23881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				}
2389e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
23901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		else {
23911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
23921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* Generate ilim digits, then fix them up. */
23931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			value(eps) *= tens[ilim-1];
23941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			for(i = 1;; i++, value(d) *= 10.) {
23951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				L = value(d);
23961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				value(d) -= L;
23971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*s++ = '0' + (int)L;
23981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (i == ilim) {
23991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					if (value(d) > 0.5 + value(eps))
24001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						goto bump_up;
24011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					else if (value(d) < 0.5 - value(eps)) {
24021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						while(*--s == '0');
24031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						s++;
24041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						goto ret1;
24051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						}
24061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					break;
24071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				}
24081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
2409e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa#ifndef No_leftright
2410e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
24111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
24121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fast_failed:
24131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		s = s0;
24141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		value(d) = value(d2);
24151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		k = k0;
24161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		ilim = ilim0;
2417e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
24181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
24191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* Do we have a "small" integer? */
24201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
24211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (be >= 0 && k <= Int_max) {
24221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/* Yes. */
24231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		ds = tens[k];
24241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (ndigits < 0 && ilim <= 0) {
24251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			S = mhi = 0;
24261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (ilim < 0 || value(d) <= 5*ds)
24271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				goto no_digits;
24281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto one_digit;
2429e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
24301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		for(i = 1;; i++) {
24311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			L = value(d) / ds;
24321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			value(d) -= L*ds;
24331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef Check_FLT_ROUNDS
24341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* If FLT_ROUNDS == 2, L will usually be high by 1 */
24351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (value(d) < 0) {
24361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				L--;
24371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				value(d) += ds;
2438e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa			}
24391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
24401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			*s++ = '0' + (int)L;
24411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (i == ilim) {
24421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				value(d) += value(d);
24431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (value(d) > ds || (value(d) == ds && L & 1)) {
24441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bump_up:
24451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					while(*--s == '9')
24461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						if (s == s0) {
24471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project							k++;
24481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project							*s = '0';
24491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project							break;
2450e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa						}
24511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					++*s++;
24521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				}
2453e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa				break;
2454e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa			}
24551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (!(value(d) *= 10.))
24561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				break;
24571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
24581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		goto ret1;
2459e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
24601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
24611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	m2 = b2;
24621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	m5 = b5;
24631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	mhi = mlo = 0;
24641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (leftright) {
24651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (mode < 2) {
24661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			i =
24671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef Sudden_Underflow
24681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				denorm ? be + (Bias + (P-1) - 1 + 1) :
24691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
24701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef IBM
24711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
24721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
24731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				1 + P - bbits;
24741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
2475e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
24761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		else {
24771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			j = ilim - 1;
24781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (m5 >= j)
24791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				m5 -= j;
24801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else {
24811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				s5 += j -= m5;
24821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				b5 += j;
24831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				m5 = 0;
2484e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa			}
24851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if ((i = ilim) < 0) {
24861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				m2 -= i;
24871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				i = 0;
24881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
2489e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
24901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		b2 += i;
24911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		s2 += i;
24921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		mhi = i2b(1);
2493e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
24941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (m2 > 0 && s2 > 0) {
24951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		i = m2 < s2 ? m2 : s2;
24961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		b2 -= i;
24971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		m2 -= i;
24981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		s2 -= i;
2499e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
25001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (b5 > 0) {
25011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (leftright) {
25021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (m5 > 0) {
25031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				mhi = pow5mult(mhi, m5);
25041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				b1 = mult(mhi, b);
25051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				Bfree(b);
25061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				b = b1;
2507e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa			}
25081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if ((j = b5 - m5) != 0)
25091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				b = pow5mult(b, j);
25101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
25111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		else
25121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			b = pow5mult(b, b5);
2513e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
25141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	S = i2b(1);
25151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (s5 > 0)
25161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		S = pow5mult(S, s5);
25171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
25181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* Check for special case that d is a normalized power of 2. */
25191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
25201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (mode < 2) {
25211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (!word1(d) && !(word0(d) & Bndry_mask)
25221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef Sudden_Underflow
25231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 && word0(d) & Exp_mask
25241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
25251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				) {
25261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* The special case */
25271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			b2 += Log2P;
25281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			s2 += Log2P;
25291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			spec_case = 1;
25301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
25311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		else
25321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			spec_case = 0;
2533e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
25341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
25351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* Arrange for convenient computation of quotients:
25361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * shift left if necessary so divisor has 4 leading 0 bits.
25371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 *
25381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * Perhaps we should just compute leading 28 bits of S once
25391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * and for all and pass them and a shift to quorem, so it
25401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * can do shifts and ors to compute the numerator for q.
25411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 */
25428132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner	if (S == BIGINT_INVALID) {
25438132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		i = 0;
25448132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner	} else {
25451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef Pack_32
25468132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) != 0)
25478132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner			i = 32 - i;
25481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
25498132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner		if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf)
25508132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner			i = 16 - i;
25511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
25528132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner	}
25538132626b71b319c71c7c4710f0c57c417badf8c0David 'Digit' Turner
25541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (i > 4) {
25551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		i -= 4;
25561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		b2 += i;
25571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		m2 += i;
25581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		s2 += i;
2559e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
25601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	else if (i < 4) {
25611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		i += 28;
25621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		b2 += i;
25631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		m2 += i;
25641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		s2 += i;
2565e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
25661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (b2 > 0)
25671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		b = lshift(b, b2);
25681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (s2 > 0)
25691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		S = lshift(S, s2);
25701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (k_check) {
25711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (cmp(b,S) < 0) {
25721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			k--;
25731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			b = multadd(b, 10, 0);	/* we botched the k estimate */
25741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (leftright)
25751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				mhi = multadd(mhi, 10, 0);
25761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ilim = ilim1;
25771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
2578e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
25791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (ilim <= 0 && mode > 2) {
25801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
25811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* no digits, fcvt style */
25821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project no_digits:
25831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			k = -1 - ndigits;
25841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto ret;
2585e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
25861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project one_digit:
25871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*s++ = '1';
25881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		k++;
25891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		goto ret;
2590e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
25911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (leftright) {
25921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (m2 > 0)
25931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			mhi = lshift(mhi, m2);
25941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
25951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/* Compute mlo -- check for special case
25961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * that d is a normalized power of 2.
25971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 */
25981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
25991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		mlo = mhi;
26001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (spec_case) {
26011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			mhi = Balloc(mhi->k);
26021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			Bcopy(mhi, mlo);
26031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			mhi = lshift(mhi, Log2P);
2604e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
26051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
26061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		for(i = 1;;i++) {
26071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			dig = quorem(b,S) + '0';
26081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* Do we yet have the shortest decimal string
26091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * that will round to d?
26101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 */
26111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			j = cmp(b, mlo);
26121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			delta = diff(S, mhi);
26131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			jj1 = delta->sign ? 1 : cmp(b, delta);
26141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			Bfree(delta);
26151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef ROUND_BIASED
26161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (jj1 == 0 && !mode && !(word1(d) & 1)) {
26171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (dig == '9')
26181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					goto round_9_up;
26191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (j > 0)
26201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					dig++;
26211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*s++ = dig;
26221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				goto ret;
2623e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa			}
26241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
26251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (j < 0 || (j == 0 && !mode
26261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef ROUND_BIASED
26271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project							&& !(word1(d) & 1)
26281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
26291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					)) {
26301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (jj1 > 0) {
26311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					b = lshift(b, 1);
26321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					jj1 = cmp(b, S);
26331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					if ((jj1 > 0 || (jj1 == 0 && dig & 1))
26341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					&& dig++ == '9')
26351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						goto round_9_up;
26361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					}
26371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*s++ = dig;
26381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				goto ret;
2639e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa			}
26401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (jj1 > 0) {
26411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (dig == '9') { /* possible if i == 1 */
26421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project round_9_up:
26431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					*s++ = '9';
26441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					goto roundoff;
26451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					}
26461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*s++ = dig + 1;
26471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				goto ret;
2648e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa			}
26491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			*s++ = dig;
26501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (i == ilim)
26511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				break;
26521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			b = multadd(b, 10, 0);
26531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (mlo == mhi)
26541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				mlo = mhi = multadd(mhi, 10, 0);
26551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else {
26561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				mlo = multadd(mlo, 10, 0);
26571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				mhi = multadd(mhi, 10, 0);
26581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
26591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
2660e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
26611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	else
26621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		for(i = 1;; i++) {
26631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			*s++ = dig = quorem(b,S) + '0';
26641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (i >= ilim)
26651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				break;
26661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			b = multadd(b, 10, 0);
2667e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa		}
26681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
26691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* Round off last digit */
26701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
26711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	b = lshift(b, 1);
26721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	j = cmp(b, S);
26731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (j > 0 || (j == 0 && dig & 1)) {
26741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project roundoff:
26751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		while(*--s == '9')
26761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (s == s0) {
26771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				k++;
26781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*s++ = '1';
26791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				goto ret;
26801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				}
26811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		++*s++;
2682e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
26831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	else {
26841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		while(*--s == '0');
26851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		s++;
2686e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
26871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ret:
26881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	Bfree(S);
26891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (mhi) {
26901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (mlo && mlo != mhi)
26911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			Bfree(mlo);
26921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		Bfree(mhi);
2693e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa	}
26941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ret1:
26951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	Bfree(b);
26961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (s == s0) {				/* don't return empty string */
26971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*s++ = '0';
26981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		k = 0;
26991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
27001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*s = 0;
27011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*decpt = k + 1;
27021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (rve)
27031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*rve = s;
27041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return s0;
2705e734769276045c0cb89d4620fdd4ef35a0e6c335André Goddard Rosa}
27061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef __cplusplus
27071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
27081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
2709