115 lines
2.8 KiB
C
115 lines
2.8 KiB
C
|
/* xxxdtent.h -- common _[FL]Dtento functionality */
|
||
|
#include "xmath.h"
|
||
|
_C_STD_BEGIN
|
||
|
#if !defined(MRTDLL)
|
||
|
_C_LIB_DECL
|
||
|
#endif /* defined(MRTDLL) */
|
||
|
|
||
|
/* macros */
|
||
|
#define ACSIZE 3 /* size of extended-precision accumulators */
|
||
|
|
||
|
#define FRAC_BITS_2 (FRAC_BITS * FRAC_BITS)
|
||
|
|
||
|
#if 113 <= FBITS
|
||
|
#define FRAC_BITS 72057594037927936.0L /* 2^56 */
|
||
|
|
||
|
static const FTYPE tenth[] =
|
||
|
{ /* 113-bit: 0.100000 */
|
||
|
(FTYPE)(FLIT(7205759403792793.0) / FRAC_BITS),
|
||
|
(FTYPE)(FLIT(43234556422756761.0) / FRAC_BITS_2),
|
||
|
(FTYPE)(FLIT(43234556422756761.0) / FRAC_BITS_2 / FRAC_BITS),
|
||
|
};
|
||
|
|
||
|
#elif 64 <= FBITS
|
||
|
#define FRAC_BITS 4294967296.0L /* 2^32 */
|
||
|
|
||
|
static const FTYPE tenth[] =
|
||
|
{ /* 64-bit: 0.100000 */
|
||
|
(FTYPE)(FLIT(429496729.0) / FRAC_BITS),
|
||
|
(FTYPE)(FLIT(2576980377.0) / FRAC_BITS_2),
|
||
|
(FTYPE)(FLIT(2576980377.0) / FRAC_BITS_2 / FRAC_BITS),
|
||
|
};
|
||
|
|
||
|
#elif 53 <= FBITS
|
||
|
#define FRAC_BITS 67108864.0L /* 2^26 */
|
||
|
|
||
|
static const FTYPE tenth[] =
|
||
|
{ /* 53-bit: 0.100000 */
|
||
|
(FTYPE)(FLIT(6710886.0) / FRAC_BITS),
|
||
|
(FTYPE)(FLIT(26843545.0) / FRAC_BITS_2),
|
||
|
(FTYPE)(FLIT(40265318.0) / FRAC_BITS_2 / FRAC_BITS),
|
||
|
};
|
||
|
|
||
|
#elif 24 <= FBITS
|
||
|
#define FRAC_BITS 4096.0L /* 2^12 */
|
||
|
|
||
|
static const FTYPE tenth[] =
|
||
|
{ /* 24-bit: 0.100000 */
|
||
|
(FTYPE)(FLIT(409.0) / FRAC_BITS),
|
||
|
(FTYPE)(FLIT(2457.0) / FRAC_BITS_2),
|
||
|
(FTYPE)(FLIT(2457.0) / FRAC_BITS_2 / FRAC_BITS),
|
||
|
};
|
||
|
|
||
|
#elif 11 <= FBITS
|
||
|
#define FRAC_BITS 32.0 /* 2^5 */
|
||
|
|
||
|
static const FTYPE tenth[] =
|
||
|
{ /* 11-bit: 0.100000 */
|
||
|
FTYPE(3.0 / FRAC_BITS),
|
||
|
FTYPE(6.0 / FRAC_BITS_2),
|
||
|
FTYPE(13.0 / FRAC_BITS_2 / FRAC_BITS),
|
||
|
};
|
||
|
|
||
|
#else /* FBITS */
|
||
|
#error _Dtento has too much precision
|
||
|
#endif /* FBITS */
|
||
|
|
||
|
_CRTIMP2_PURE FTYPE __CLRCALL_PURE_OR_CDECL FNAME(Dtento)(FTYPE *xpx, long n, int *perr)
|
||
|
{ /* compute *px * 10**n */
|
||
|
FTYPE xpf[ACSIZE];
|
||
|
FTYPE x;
|
||
|
|
||
|
if (n == 0 || xpx[0] == FLIT(0.0))
|
||
|
return (FNAME(Xp_getw)(xpx, ACSIZE));
|
||
|
|
||
|
if (0 < n)
|
||
|
FNAME(Xp_setw)(xpf, ACSIZE, 10.0); /* factor = 10 */
|
||
|
else
|
||
|
{ /* scale down */
|
||
|
n = -n;
|
||
|
FNAME(Xp_movx)(xpf, ACSIZE, tenth); /* factor = 1/10 */
|
||
|
}
|
||
|
|
||
|
for (; ; )
|
||
|
{ /* multiply as needed by 10^(2^n) */
|
||
|
FTYPE xpt[ACSIZE * 2];
|
||
|
FTYPE xpw[ACSIZE];
|
||
|
|
||
|
if (n & 1)
|
||
|
FNAME(Xp_mulx)(xpx, ACSIZE, xpf, ACSIZE, xpt);
|
||
|
n >>= 1;
|
||
|
if (n == 0)
|
||
|
break;
|
||
|
FNAME(Xp_movx)(xpw, ACSIZE, xpf);
|
||
|
FNAME(Xp_mulx)(xpf, ACSIZE, xpw, ACSIZE, xpt); /* square 10^n */
|
||
|
}
|
||
|
|
||
|
x = FNAME(Xp_getw)(xpx, ACSIZE);
|
||
|
if (x == FLIT(0.0) || x == FCONST(Inf) || x == -FCONST(Inf))
|
||
|
{ /* report error and set errno */
|
||
|
errno = ERANGE;
|
||
|
if (perr != 0)
|
||
|
*perr |= 1;
|
||
|
}
|
||
|
return (x);
|
||
|
}
|
||
|
#if !defined(MRTDLL)
|
||
|
_END_C_LIB_DECL
|
||
|
#endif /* !defined(MRTDLL) */
|
||
|
_C_STD_END
|
||
|
|
||
|
/*
|
||
|
* Copyright (c) 1992-2012 by P.J. Plauger. ALL RIGHTS RESERVED.
|
||
|
* Consult your license regarding permissions and restrictions.
|
||
|
V6.00:0009 */
|