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