4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/* $NetBSD: strtodg.c,v 1.5.14.1 2008/04/08 21:10:55 jdc Exp $ */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/****************************************************************
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncThe author of this software is David M. Gay.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCopyright (C) 1998-2001 by Lucent Technologies
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncAll Rights Reserved
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPermission to use, copy, modify, and distribute this software and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncits documentation for any purpose and without fee is hereby
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncgranted, provided that the above copyright notice appear in all
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsynccopies and that both that the copyright notice and this
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncpermission notice and warranty disclaimer appear in supporting
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncdocumentation, and that the name of Lucent or any of its entities
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncnot be used in advertising or publicity pertaining to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncdistribution of the software without specific, written prior
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncpermission.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncLUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncTHIS SOFTWARE.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync****************************************************************/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/* Please send bug reports to David M. Gay (dmg at acm dot org,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * with " at " changed at "@" and " dot " changed to "."). */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <LibConfig.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include "gdtoaimp.h"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifdef USE_LOCALE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include "locale.h"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#if defined(_MSC_VER)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Disable warnings about assignment within conditional expressions.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync #pragma warning ( disable : 4706 )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync static CONST int
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncfivesbits[] = { 0, 3, 5, 7, 10, 12, 14, 17, 19, 21,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 24, 26, 28, 31, 33, 35, 38, 40, 42, 45,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 47, 49, 52
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifdef VAX
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync , 54, 56
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync };
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Bigint *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifdef KR_headers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncincrement(b) Bigint *b;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncincrement(Bigint *b)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ULong *x, *xe;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Bigint *b1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifdef Pack_16
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ULong carry = 1, y;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync x = b->x;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync xe = x + b->wds;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifdef Pack_32
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync do {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (*x < (ULong)0xffffffffL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ++*x;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return b;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *x++ = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } while(x < xe);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync do {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync y = *x + carry;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync carry = y >> 16;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *x++ = y & 0xffff;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!carry)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return b;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } while(x < xe);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (carry)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (b->wds >= b->maxwds) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync b1 = Balloc(b->k+1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (b1 == NULL)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Bcopy(b1,b);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Bfree(b);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync b = b1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync b->x[b->wds++] = 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return b;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifdef KR_headers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncdecrement(b) Bigint *b;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncdecrement(Bigint *b)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ULong *x, *xe;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifdef Pack_16
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ULong borrow = 1, y;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync x = b->x;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync xe = x + b->wds;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifdef Pack_32
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync do {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (*x) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync --*x;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *x++ = 0xffffffffUL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while(x < xe);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync do {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync y = *x - borrow;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync borrow = (y & 0x10000) >> 16;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *x++ = y & 0xffff;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } while(borrow && x < xe);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return STRTOG_Inexlo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync static int
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifdef KR_headers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncall_on(b, n) CONST Bigint *b; int n;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncall_on(CONST Bigint *b, int n)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CONST ULong *x, *xe;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync x = b->x;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync xe = x + ((unsigned int)n >> kshift);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while(x < xe)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((*x++ & ALL_ON) != ALL_ON)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (n &= kmask)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return ((*x | (ALL_ON << n)) & ALL_ON) == ALL_ON;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Bigint *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifdef KR_headers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncset_ones(b, n) Bigint *b; int n;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncset_ones(Bigint *b, int n)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int k;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ULong *x, *xe;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync k = (unsigned int)(n + ((1 << kshift) - 1)) >> kshift;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (b->k < k) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Bfree(b);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync b = Balloc(k);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (b == NULL)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync k = (unsigned int)n >> kshift;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (n &= kmask)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync k++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync b->wds = k;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync x = b->x;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync xe = x + k;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while(x < xe)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *x++ = ALL_ON;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (n)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync x[-1] >>= ULbits - n;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return b;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync static int
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncrvOK
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifdef KR_headers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (d, fpi, expt, bits, exact, rd, irv)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync double d; CONST FPI *fpi; Long *expt; ULong *bits; int exact, rd, *irv;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (double d, CONST FPI *fpi, Long *expt, ULong *bits, int exact, int rd, int *irv)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Bigint *b;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ULong carry, inex, lostbits;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int bdif, e, j, k, k1, nb, rv;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync carry = rv = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync b = d2b(d, &e, &bdif);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bdif -= nb = fpi->nbits;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync e += bdif;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (bdif <= 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (exact)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto trunc;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ret;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (P == nb) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifndef IMPRECISE_INEXACT
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync exact &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fpi->rounding ==
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifdef RND_PRODQUOT
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FPI_Round_near
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Flt_Rounds
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ) goto trunc;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ret;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch(rd) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 1:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto trunc;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 2:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default: /* round near */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync k = bdif - 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!k) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!exact)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ret;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (b->x[0] & 2)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto trunc;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (b->x[(unsigned int)k>>kshift] & ((ULong)1 << (k & kmask)))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto trunc;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* "break" cases: round up 1 bit, then truncate; bdif > 0 */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync carry = 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync trunc:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync inex = lostbits = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (bdif > 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( (lostbits = any_on(b, bdif)) !=0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync inex = STRTOG_Inexlo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rshift(b, bdif);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (carry) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync inex = STRTOG_Inexhi;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync b = increment(b);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( (j = nb & kmask) !=0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync j = ULbits - j;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (hi0bits(b->x[b->wds - 1]) != j) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!lostbits)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync lostbits = b->x[0] & 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rshift(b, 1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync e++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if (bdif < 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync b = lshift(b, -bdif);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (e < fpi->emin) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync k = fpi->emin - e;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync e = fpi->emin;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (k > nb || fpi->sudden_underflow) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync inex = b->wds = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *irv = STRTOG_Underflow | STRTOG_Inexlo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync k1 = k - 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (k1 > 0 && !lostbits)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync lostbits = any_on(b, k1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!lostbits && !exact)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ret;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync lostbits |=
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync carry = b->x[(unsigned int)k1>>kshift] &
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (ULong)(1 << ((unsigned int)k1 & kmask));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rshift(b, k);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *irv = STRTOG_Denormal;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (carry) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync b = increment(b);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync inex = STRTOG_Inexhi | STRTOG_Underflow;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if (lostbits)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync inex = STRTOG_Inexlo | STRTOG_Underflow;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if (e > fpi->emax) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync e = fpi->emax + 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *irv = STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifndef NO_ERRNO
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync errno = ERANGE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync inex = b->wds = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *expt = e;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync copybits(bits, nb, b);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *irv |= inex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rv = 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ret:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Bfree(b);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return rv;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifndef VAX
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync static int
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifdef KR_headers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncmantbits(d) double d;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncmantbits(double d)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ULong L;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifdef VAX
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync L = word1(d) << 16 | word1(d) >> 16;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (L)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( (L = word1(d)) !=0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return P - lo0bits(&L);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifdef VAX
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync L = word0(d) << 16 | word0(d) >> 16 | Exp_msk11;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync L = word0(d) | Exp_msk1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return P - 32 - lo0bits(&L);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif /* !VAX */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstrtodg
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifdef KR_headers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (s00, se, fpi, expt, bits)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CONST char *s00; char **se; CONST FPI *fpi; Long *expt; ULong *bits;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (CONST char *s00, char **se, CONST FPI *fpi, Long *expt, ULong *bits)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int abe, abits, asub;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int bb0, bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, denorm;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int dsign, e, e1, e2, emin, esign, finished, i, inex, irv;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int j, k, nbits, nd, nd0, nf, nz, nz0, rd, rvbits, rve, rve1, sign;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int sudden_underflow = 0; /* pacify gcc */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CONST char *s, *s0, *s1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync double adj, adj0, rv, tol;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Long L;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ULong y, z;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Bigint *ab, *bb, *bb1, *bd, *bd0, *bs, *delta, *rvb, *rvb0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync e2 = 0; /* XXX gcc */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync irv = STRTOG_Zero;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync denorm = sign = nz0 = nz = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync dval(rv) = 0.;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rvb = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nbits = fpi->nbits;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for(s = s00;;s++) switch(*s) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case '-':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sign = 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* FALLTHROUGH */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case '+':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (*++s)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto break2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* FALLTHROUGH */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 0:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sign = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync irv = STRTOG_NoNumber;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync s = s00;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ret;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case '\t':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case '\n':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case '\v':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case '\f':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case '\r':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ' ':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto break2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break2:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (*s == '0') {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifndef NO_HEX_FP
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch(s[1]) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'x':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'X':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync irv = gethex(&s, fpi, expt, &rvb, sign);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (irv == STRTOG_NoNumber) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync s = s00;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sign = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ret;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nz0 = 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while(*++s == '0') ;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!*s)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ret;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sudden_underflow = fpi->sudden_underflow;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync s0 = s;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync y = z = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for(decpt = nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (nd < 9)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync y = 10*y + c - '0';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if (nd < 16)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync z = 10*z + c - '0';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nd0 = nd;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifdef USE_LOCALE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (c == *localeconv()->decimal_point)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (c == '.')
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync decpt = 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync c = *++s;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!nd) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for(; c == '0'; c = *++s)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nz++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (c > '0' && c <= '9') {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync s0 = s;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nf += nz;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nz = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto have_dig;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto dig_done;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for(; c >= '0' && c <= '9'; c = *++s) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync have_dig:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nz++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (c -= '0') {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nf += nz;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for(i = 1; i < nz; i++)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (nd++ < 9)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync y *= 10;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if (nd <= DBL_DIG + 1)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync z *= 10;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (nd++ < 9)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync y = 10*y + c;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if (nd <= DBL_DIG + 1)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync z = 10*z + c;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nz = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync dig_done:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync e = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (c == 'e' || c == 'E') {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!nd && !nz && !nz0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync irv = STRTOG_NoNumber;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync s = s00;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ret;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync s00 = s;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync esign = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch(c = *++s) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case '-':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync esign = 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* FALLTHROUGH */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case '+':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync c = *++s;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (c >= '0' && c <= '9') {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while(c == '0')
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync c = *++s;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (c > '0' && c <= '9') {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync L = c - '0';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync s1 = s;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while((c = *++s) >= '0' && c <= '9')
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync L = 10*L + c - '0';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (s - s1 > 8 || L > 19999)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* Avoid confusion from exponents
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * so large that e might overflow.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync e = 19999; /* safe for 16 bit ints */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync e = (int)L;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (esign)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync e = -e;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync e = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync s = s00;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!nd) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!nz && !nz0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifdef INFNAN_CHECK
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* Check for Nan and Infinity */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!decpt)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch(c) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'i':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'I':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (match(&s,"nf")) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync --s;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!match(&s,"inity"))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ++s;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync irv = STRTOG_Infinite;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto infnanexp;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'n':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'N':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (match(&s, "an")) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync irv = STRTOG_NaN;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *expt = fpi->emax + 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifndef No_Hex_NaN
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (*s == '(') /*)*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync irv = hexnan(&s, fpi, bits);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto infnanexp;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif /* INFNAN_CHECK */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync irv = STRTOG_NoNumber;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync s = s00;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ret;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync irv = STRTOG_Normal;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync e1 = e -= nf;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rd = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch(fpi->rounding & 3) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case FPI_Round_up:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rd = 2 - sign;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case FPI_Round_zero:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rd = 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case FPI_Round_down:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rd = 1 + sign;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* Now we have nd0 digits, starting at s0, followed by a
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * decimal point, followed by nd-nd0 digits. The number we're
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * after is the integer represented by those digits times
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * 10**e */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!nd0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nd0 = nd;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync dval(rv) = (double)y;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (k > 9)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync dval(rv) = tens[k - 9] * dval(rv) + z;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bd0 = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (nbits <= P && nd <= DBL_DIG) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!e) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (rvOK(dval(rv), fpi, expt, bits, 1, rd, &irv))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ret;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if (e > 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (e <= Ten_pmax) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifdef VAX
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto vax_ovfl_check;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync i = fivesbits[e] + mantbits(dval(rv)) <= P;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* rv = */ rounded_product(dval(rv), tens[e]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (rvOK(dval(rv), fpi, expt, bits, i, rd, &irv))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ret;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync e1 -= e;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto rv_notOK;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync i = DBL_DIG - nd;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (e <= Ten_pmax + i) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* A fancier test would sometimes let us do
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * this for larger i values.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync e2 = e - i;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync e1 -= i;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync dval(rv) *= tens[i];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifdef VAX
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* VAX exponent range is so narrow we must
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * worry about overflow here...
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync vax_ovfl_check:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync dval(adj) = dval(rv);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync word0(adj) -= P*Exp_msk1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* adj = */ rounded_product(dval(adj), tens[e2]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((word0(adj) & Exp_mask)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto rv_notOK;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync word0(adj) += P*Exp_msk1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync dval(rv) = dval(adj);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* rv = */ rounded_product(dval(rv), tens[e2]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (rvOK(dval(rv), fpi, expt, bits, 0, rd, &irv))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ret;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync e1 -= e2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifndef Inaccurate_Divide
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if (e >= -Ten_pmax) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* rv = */ rounded_quotient(dval(rv), tens[-e]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (rvOK(dval(rv), fpi, expt, bits, 0, rd, &irv))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ret;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync e1 -= e;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rv_notOK:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync e1 += nd - k;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* Get starting approximation = rv * 10**e1 */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync e2 = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (e1 > 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( (i = e1 & 15) !=0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync dval(rv) *= tens[i];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (e1 &= ~15) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync e1 = (unsigned int)e1 >> 4;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while(e1 >= (1 << (n_bigtens-1))) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync e2 += ((word0(rv) & Exp_mask)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync >> Exp_shift1) - Bias;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync word0(rv) &= ~Exp_mask;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync word0(rv) |= Bias << Exp_shift1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync dval(rv) *= bigtens[n_bigtens-1];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync e1 -= 1 << (n_bigtens-1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync e2 += ((word0(rv) & Exp_mask) >> Exp_shift1) - Bias;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync word0(rv) &= ~Exp_mask;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync word0(rv) |= Bias << Exp_shift1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for(j = 0; e1 > 0; j++, e1 = (unsigned int)e1 >> 1)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (e1 & 1)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync dval(rv) *= bigtens[j];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if (e1 < 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync e1 = -e1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( (i = e1 & 15) !=0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync dval(rv) /= tens[i];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (e1 &= ~15) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync e1 = (unsigned int)e1 >> 4;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while(e1 >= (1 << (n_bigtens-1))) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync e2 += ((word0(rv) & Exp_mask)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync >> Exp_shift1) - Bias;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync word0(rv) &= ~Exp_mask;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync word0(rv) |= Bias << Exp_shift1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync dval(rv) *= tinytens[n_bigtens-1];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync e1 -= 1 << (n_bigtens-1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync e2 += ((word0(rv) & Exp_mask) >> Exp_shift1) - Bias;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync word0(rv) &= ~Exp_mask;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync word0(rv) |= Bias << Exp_shift1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for(j = 0; e1 > 0; j++, e1 = (unsigned int)e1 >> 1)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (e1 & 1)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync dval(rv) *= tinytens[j];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifdef IBM
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* e2 is a correction to the (base 2) exponent of the return
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * value, reflecting adjustments above to avoid overflow in the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * native arithmetic. For native IBM (base 16) arithmetic, we
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * must multiply e2 by 4 to change from base 16 to 2.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync e2 <<= 2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rvb = d2b(dval(rv), &rve, &rvbits); /* rv = rvb * 2^rve */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (rvb == NULL)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return STRTOG_NoMemory;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rve += e2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((j = rvbits - nbits) > 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rshift(rvb, j);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rvbits = nbits;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rve += j;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bb0 = 0; /* trailing zero bits in rvb */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync e2 = rve + rvbits - nbits;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (e2 > fpi->emax + 1)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto huge;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rve1 = rve + rvbits - nbits;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (e2 < (emin = fpi->emin)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync denorm = 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync j = rve - emin;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (j > 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rvb = lshift(rvb, j);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rvbits += j;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if (j < 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rvbits += j;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (rvbits <= 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (rvbits < -1) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ufl:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rvb->wds = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rvb->x[0] = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *expt = emin;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync irv = STRTOG_Underflow | STRTOG_Inexlo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ret;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rvb->x[0] = rvb->wds = rvbits = 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rshift(rvb, -j);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rve = rve1 = emin;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (sudden_underflow && e2 + 1 < emin)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ufl;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* Now the hard part -- adjusting rv to the correct value.*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* Put digits into bd: true value = bd * 10^e */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bd0 = s2b(s0, nd0, nd, y);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for(;;) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bd = Balloc(bd0->k);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (bd == NULL)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return STRTOG_NoMemory;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Bcopy(bd, bd0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bb = Balloc(rvb->k);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (bb == NULL)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return STRTOG_NoMemory;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Bcopy(bb, rvb);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bbbits = rvbits - bb0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bbe = rve + bb0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bs = i2b(1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (bs == NULL)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return STRTOG_NoMemory;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (e >= 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bb2 = bb5 = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bd2 = bd5 = e;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bb2 = bb5 = -e;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bd2 = bd5 = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (bbe >= 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bb2 += bbe;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bd2 -= bbe;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bs2 = bb2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync j = nbits + 1 - bbbits;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync i = bbe + bbbits - nbits;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (i < emin) /* denormal */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync j += i - emin;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bb2 += j;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bd2 += j;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync i = bb2 < bd2 ? bb2 : bd2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (i > bs2)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync i = bs2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (i > 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bb2 -= i;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bd2 -= i;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bs2 -= i;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (bb5 > 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bs = pow5mult(bs, bb5);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (bs == NULL)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return STRTOG_NoMemory;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bb1 = mult(bs, bb);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (bb1 == NULL)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return STRTOG_NoMemory;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Bfree(bb);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bb = bb1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bb2 -= bb0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (bb2 > 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bb = lshift(bb, bb2);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (bb == NULL)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return STRTOG_NoMemory;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if (bb2 < 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rshift(bb, -bb2);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (bd5 > 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bd = pow5mult(bd, bd5);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (bd == NULL)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return STRTOG_NoMemory;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (bd2 > 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bd = lshift(bd, bd2);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (bd == NULL)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return STRTOG_NoMemory;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (bs2 > 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bs = lshift(bs, bs2);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (bs == NULL)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return STRTOG_NoMemory;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync asub = 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync inex = STRTOG_Inexhi;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync delta = diff(bb, bd);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (delta == NULL)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return STRTOG_NoMemory;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (delta->wds <= 1 && !delta->x[0])
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync dsign = delta->sign;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync delta->sign = finished = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync L = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync i = cmp(delta, bs);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (rd && i <= 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync irv = STRTOG_Normal;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( (finished = dsign ^ (rd&1)) !=0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (dsign != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync irv |= STRTOG_Inexhi;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto adj1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync irv |= STRTOG_Inexlo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (rve1 == emin)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto adj1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for(i = 0, j = nbits; j >= ULbits;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync i++, j -= ULbits) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (rvb->x[i] & ALL_ON)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto adj1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (j > 1 && lo0bits(rvb->x + i) < j - 1)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto adj1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rve = rve1 - 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rvb = set_ones(rvb, rvbits = nbits);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (rvb == NULL)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return STRTOG_NoMemory;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync irv |= dsign ? STRTOG_Inexlo : STRTOG_Inexhi;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (i < 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* Error is less than half an ulp -- check for
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * special case of mantissa a power of two.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync irv = dsign
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ? STRTOG_Normal | STRTOG_Inexlo
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync : STRTOG_Normal | STRTOG_Inexhi;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (dsign || bbbits > 1 || denorm || rve1 == emin)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync delta = lshift(delta,1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (delta == NULL)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return STRTOG_NoMemory;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (cmp(delta, bs) > 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync irv = STRTOG_Normal | STRTOG_Inexlo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto drop_down;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (i == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* exactly half-way between */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (dsign) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (denorm && all_on(rvb, rvbits)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /*boundary case -- increment exponent*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rvb->wds = 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rvb->x[0] = 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rve = emin + nbits - (rvbits = 1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync irv = STRTOG_Normal | STRTOG_Inexhi;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync denorm = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync irv = STRTOG_Normal | STRTOG_Inexlo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if (bbbits == 1) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync irv = STRTOG_Normal;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync drop_down:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* boundary case -- decrement exponent */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (rve1 == emin) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync irv = STRTOG_Normal | STRTOG_Inexhi;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (rvb->wds == 1 && rvb->x[0] == 1)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sudden_underflow = 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rve -= nbits;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rvb = set_ones(rvb, rvbits = nbits);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (rvb == NULL)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return STRTOG_NoMemory;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync irv = STRTOG_Normal | STRTOG_Inexhi;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((bbbits < nbits && !denorm) || !(rvb->x[0] & 1))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (dsign) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rvb = increment(rvb);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (rvb == NULL)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return STRTOG_NoMemory;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( (j = rvbits & kmask) !=0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync j = ULbits - j;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (hi0bits(rvb->x[(unsigned int)(rvb->wds - 1)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync >> kshift])
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync != j)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rvbits++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync irv = STRTOG_Normal | STRTOG_Inexhi;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (bbbits == 1)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto undfl;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync decrement(rvb);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync irv = STRTOG_Normal | STRTOG_Inexlo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((dval(adj) = ratio(delta, bs)) <= 2.) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync adj1:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync inex = STRTOG_Inexlo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (dsign) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync asub = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync inex = STRTOG_Inexhi;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if (denorm && bbbits <= 1) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync undfl:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rvb->wds = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rve = emin;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync irv = STRTOG_Underflow | STRTOG_Inexlo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync adj0 = dval(adj) = 1.;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync adj0 = dval(adj) *= 0.5;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (dsign) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync asub = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync inex = STRTOG_Inexlo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (dval(adj) < 2147483647.) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync L = (INT32)adj0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync adj0 -= L;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch(rd) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 0:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (adj0 >= .5)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto inc_L;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 1:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (asub && adj0 > 0.)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto inc_L;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 2:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!asub && adj0 > 0.) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync inc_L:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync L++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync inex = STRTOG_Inexact - inex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync dval(adj) = (double)L;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync y = rve + rvbits;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* adj *= ulp(dval(rv)); */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* if (asub) rv -= adj; else rv += adj; */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!denorm && rvbits < nbits) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rvb = lshift(rvb, j = nbits - rvbits);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (rvb == NULL)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return STRTOG_NoMemory;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rve -= j;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rvbits = nbits;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ab = d2b(dval(adj), &abe, &abits);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ab == NULL)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return STRTOG_NoMemory;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (abe < 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rshift(ab, -abe);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if (abe > 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ab = lshift(ab, abe);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rvb0 = rvb;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (asub) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* rv -= adj; */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync j = hi0bits(rvb->x[rvb->wds-1]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rvb = diff(rvb, ab);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (rvb == NULL)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return STRTOG_NoMemory;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync k = rvb0->wds - 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (denorm)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* do nothing */;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if (rvb->wds <= k
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync || hi0bits( rvb->x[k]) >
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync hi0bits(rvb0->x[k])) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* unlikely; can only have lost 1 high bit */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (rve1 == emin) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync --rvbits;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync denorm = 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rvb = lshift(rvb, 1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (rvb == NULL)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return STRTOG_NoMemory;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync --rve;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync --rve1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync L = finished = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rvb = sum(rvb, ab);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (rvb == NULL)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return STRTOG_NoMemory;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync k = rvb->wds - 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (k >= rvb0->wds
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync || hi0bits(rvb->x[k]) < hi0bits(rvb0->x[k])) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (denorm) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (++rvbits == nbits)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync denorm = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rshift(rvb, 1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rve++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rve1++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync L = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Bfree(ab);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Bfree(rvb0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (finished)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync z = rve + rvbits;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (y == z && L) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* Can we stop now? */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync tol = dval(adj) * 5e-16; /* > max rel error */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync dval(adj) = adj0 - .5;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (dval(adj) < -tol) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (adj0 > tol) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync irv |= inex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if (dval(adj) > tol && adj0 < 1. - tol) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync irv |= inex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bb0 = denorm ? 0 : trailz(rvb);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Bfree(bb);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Bfree(bd);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Bfree(bs);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Bfree(delta);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!denorm && (j = nbits - rvbits)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (j > 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rvb = lshift(rvb, j);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rshift(rvb, -j);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rve -= j;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *expt = rve;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Bfree(bb);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Bfree(bd);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Bfree(bs);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Bfree(bd0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Bfree(delta);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (rve > fpi->emax) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync huge:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rvb->wds = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync irv = STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifndef NO_ERRNO
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync errno = ERANGE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifdef INFNAN_CHECK
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync infnanexp:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *expt = fpi->emax + 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ret:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (denorm) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (sudden_underflow) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rvb->wds = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync irv = STRTOG_Underflow | STRTOG_Inexlo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync irv = (irv & ~STRTOG_Retmask) |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (rvb->wds > 0 ? STRTOG_Denormal : STRTOG_Zero);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (irv & STRTOG_Inexact)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync irv |= STRTOG_Underflow;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (se)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *se = __UNCONST(s);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (sign)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync irv |= STRTOG_Neg;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (rvb) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync copybits(bits, nbits, rvb);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Bfree(rvb);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return irv;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }