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