mirror of
https://git.code.sf.net/p/mingw-w64/mingw-w64
synced 2024-11-23 18:04:18 +08:00
2009-04-15 Ozkan Sezer <sezeroz@gmail.com>
* gdtoa/gdtoa_fltrnds.h: New. * gdtoa/README, gdtoa/g_dfmt.c, gdtoa/g_ffmt.c, gdtoa/g_xfmt.c, gdtoa/gdtoaimp.h, gdtoa/strtof.c, gdtoa/strtopx.c: Merged in the Honor_FLT_ROUNDS/fegetround() bits from the current netlib.org sources. git-svn-id: svn+ssh://svn.code.sf.net/p/mingw-w64/code/trunk@776 4407c894-4637-0410-b4f5-ada5f102cad1
This commit is contained in:
parent
b49043572b
commit
fef98cff07
@ -3,6 +3,11 @@
|
||||
* gdtoa/dtoa.c, gdtoa/gdtoa.c: Sync'ed with the netlib.org sources.
|
||||
* gdtoa/gdtoa.h: Minor cleanup.
|
||||
|
||||
* gdtoa/gdtoa_fltrnds.h: New.
|
||||
* gdtoa/README, gdtoa/g_dfmt.c, gdtoa/g_ffmt.c, gdtoa/g_xfmt.c,
|
||||
gdtoa/gdtoaimp.h, gdtoa/strtof.c, gdtoa/strtopx.c: Merged in the
|
||||
Honor_FLT_ROUNDS/fegetround() bits from the current netlib.org sources.
|
||||
|
||||
2009-04-14 Ozkan Sezer <sezeroz@gmail.com>
|
||||
|
||||
* gdtoa/dmisc.c, gdtoa/dtoa.c, gdtoa/gdtoa.c, gdtoa/gdtoa.h,
|
||||
|
@ -56,7 +56,9 @@ two letters:
|
||||
whose sum is the desired value
|
||||
|
||||
For decimal -> binary conversions, there are three families of
|
||||
helper routines: one for round-nearest:
|
||||
helper routines: one for round-nearest (or the current rounding
|
||||
mode on IEEE-arithmetic systems that provide the C99 fegetround()
|
||||
function, if compiled with -DHonor_FLT_ROUNDS):
|
||||
|
||||
strtof
|
||||
strtod
|
||||
@ -191,6 +193,9 @@ in the buffer, if the buffer was long enough, or 0. Other forms of
|
||||
conversion are easily done with the help of gdtoa(), such as %e or %f
|
||||
style and conversions with direction of rounding specified (so that, if
|
||||
desired, the decimal value is either >= or <= the binary value).
|
||||
On IEEE-arithmetic systems that provide the C99 fegetround() function,
|
||||
if compiled with -DHonor_FLT_ROUNDS, these routines honor the current
|
||||
rounding mode.
|
||||
|
||||
For an example of more general conversions based on dtoa(), see
|
||||
netlib's "printf.c from ampl/solvers".
|
||||
@ -332,5 +337,15 @@ Compiling g__fmt.c, strtod.c, and strtodg.c with -DUSE_LOCALE causes
|
||||
the decimal-point character to be taken from the current locale; otherwise
|
||||
it is '.'.
|
||||
|
||||
Source files dtoa.c and strtod.c in this directory are derived from
|
||||
netlib's "dtoa.c from fp" and are meant to function equivalently.
|
||||
When compiled with Honor_FLT_ROUNDS #defined (on systems that provide
|
||||
FLT_ROUNDS and fegetround() as specified in the C99 standard), they
|
||||
honor the current rounding mode. Because FLT_ROUNDS is buggy on some
|
||||
(Linux) systems -- not reflecting calls on fesetround(), as the C99
|
||||
standard says it should -- when Honor_FLT_ROUNDS is #defined, the
|
||||
current rounding mode is obtained from fegetround() rather than from
|
||||
FLT_ROUNDS, unless Trust_FLT_ROUNDS is also #defined.
|
||||
|
||||
Please send comments to David M. Gay (dmg at acm dot org, with " at "
|
||||
changed at "@" and " dot " changed to ".").
|
||||
|
@ -33,10 +33,15 @@ THIS SOFTWARE.
|
||||
|
||||
char *__g_dfmt (char *buf, double *d, int ndig, unsigned bufsize)
|
||||
{
|
||||
static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, 0 };
|
||||
static FPI fpi0 = { 53, 1-1023-53+1, 2046-1023-53+1, 1, 0 };
|
||||
char *b, *s, *se;
|
||||
ULong bits[2], *L, sign;
|
||||
int decpt, ex, i, mode;
|
||||
#ifdef Honor_FLT_ROUNDS
|
||||
#include "gdtoa_fltrnds.h"
|
||||
#else
|
||||
#define fpi &fpi0
|
||||
#endif
|
||||
|
||||
if (ndig < 0)
|
||||
ndig = 0;
|
||||
@ -79,6 +84,6 @@ char *__g_dfmt (char *buf, double *d, int ndig, unsigned bufsize)
|
||||
mode = 0;
|
||||
}
|
||||
i = STRTOG_Normal;
|
||||
s = __gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se);
|
||||
s = __gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se);
|
||||
return __g__fmt(buf, s, se, decpt, sign);
|
||||
}
|
||||
|
@ -33,10 +33,15 @@ THIS SOFTWARE.
|
||||
|
||||
char *__g_ffmt (char *buf, float *f, int ndig, unsigned bufsize)
|
||||
{
|
||||
static FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, 0 };
|
||||
static FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, 0 };
|
||||
char *b, *s, *se;
|
||||
ULong bits[1], *L, sign;
|
||||
int decpt, ex, i, mode;
|
||||
#ifdef Honor_FLT_ROUNDS
|
||||
#include "gdtoa_fltrnds.h"
|
||||
#else
|
||||
#define fpi &fpi0
|
||||
#endif
|
||||
|
||||
if (ndig < 0)
|
||||
ndig = 0;
|
||||
@ -49,7 +54,7 @@ char *__g_ffmt (char *buf, float *f, int ndig, unsigned bufsize)
|
||||
/* Infinity or NaN */
|
||||
if (L[0] & 0x7fffff) {
|
||||
return strcp(buf, "NaN");
|
||||
}
|
||||
}
|
||||
b = buf;
|
||||
if (sign)
|
||||
*b++ = '-';
|
||||
@ -78,6 +83,6 @@ char *__g_ffmt (char *buf, float *f, int ndig, unsigned bufsize)
|
||||
mode = 0;
|
||||
}
|
||||
i = STRTOG_Normal;
|
||||
s = __gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se);
|
||||
s = __gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se);
|
||||
return __g__fmt(buf, s, se, decpt, sign);
|
||||
}
|
||||
|
@ -53,14 +53,18 @@ THIS SOFTWARE.
|
||||
|
||||
char *__g_xfmt (char *buf, void *V, int ndig, unsigned bufsize)
|
||||
{
|
||||
static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0 };
|
||||
static FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0 };
|
||||
char *b, *s, *se;
|
||||
ULong bits[2], sign;
|
||||
UShort *L;
|
||||
int decpt, ex, i, mode;
|
||||
|
||||
int fptype = __fpclassifyl (*(long double*) V);
|
||||
|
||||
#ifdef Honor_FLT_ROUNDS
|
||||
#include "gdtoa_fltrnds.h"
|
||||
#else
|
||||
#define fpi &fpi0
|
||||
#endif
|
||||
|
||||
if (ndig < 0)
|
||||
ndig = 0;
|
||||
if (bufsize < ndig + 10)
|
||||
@ -68,8 +72,7 @@ char *__g_xfmt (char *buf, void *V, int ndig, unsigned bufsize)
|
||||
|
||||
L = (UShort *)V;
|
||||
sign = L[_0] & 0x8000;
|
||||
ex = L[_0] & 0x7fff;
|
||||
|
||||
ex = L[_0] & 0x7fff;
|
||||
bits[1] = (L[_1] << 16) | L[_2];
|
||||
bits[0] = (L[_3] << 16) | L[_4];
|
||||
|
||||
@ -102,7 +105,6 @@ char *__g_xfmt (char *buf, void *V, int ndig, unsigned bufsize)
|
||||
*b = 0;
|
||||
return b;
|
||||
}
|
||||
|
||||
ex -= 0x3fff + 63;
|
||||
mode = 2;
|
||||
if (ndig <= 0) {
|
||||
@ -110,6 +112,6 @@ char *__g_xfmt (char *buf, void *V, int ndig, unsigned bufsize)
|
||||
return 0;
|
||||
mode = 0;
|
||||
}
|
||||
s = __gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se);
|
||||
s = __gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se);
|
||||
return __g__fmt(buf, s, se, decpt, sign);
|
||||
}
|
||||
|
18
mingw-w64-crt/gdtoa/gdtoa_fltrnds.h
Normal file
18
mingw-w64-crt/gdtoa/gdtoa_fltrnds.h
Normal file
@ -0,0 +1,18 @@
|
||||
FPI *fpi, fpi1;
|
||||
int Rounding;
|
||||
#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */
|
||||
Rounding = Flt_Rounds;
|
||||
#else /*}{*/
|
||||
Rounding = 1;
|
||||
switch(fegetround()) {
|
||||
case FE_TOWARDZERO: Rounding = 0; break;
|
||||
case FE_UPWARD: Rounding = 2; break;
|
||||
case FE_DOWNWARD: Rounding = 3;
|
||||
}
|
||||
#endif /*}}*/
|
||||
fpi = &fpi0;
|
||||
if (Rounding != 1) {
|
||||
fpi1 = fpi0;
|
||||
fpi = &fpi1;
|
||||
fpi1.rounding = Rounding;
|
||||
}
|
@ -170,6 +170,10 @@ THIS SOFTWARE.
|
||||
#define USE_LOCALE 1
|
||||
#endif /* MinGW */
|
||||
|
||||
#ifdef Honor_FLT_ROUNDS
|
||||
#include <fenv.h>
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <stdio.h>
|
||||
#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
|
||||
@ -448,7 +452,7 @@ typedef struct Bigint Bigint;
|
||||
#ifdef DECLARE_SIZE_T
|
||||
typedef unsigned int size_t;
|
||||
#endif
|
||||
extern void memcpy_D2A (void *, const void *, size_t);
|
||||
extern void memcpy_D2A (void*, const void*, size_t);
|
||||
#define Bcopy(x,y) memcpy_D2A(&x->sign,&y->sign,y->wds*sizeof(ULong) + 2*sizeof(int))
|
||||
#else /* !NO_STRING_H */
|
||||
#define Bcopy(x,y) memcpy(&x->sign,&y->sign,y->wds*sizeof(ULong) + 2*sizeof(int))
|
||||
|
@ -33,13 +33,18 @@ THIS SOFTWARE.
|
||||
|
||||
float __strtof (const char *s, char **sp)
|
||||
{
|
||||
static FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, SI };
|
||||
static FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, SI };
|
||||
ULong bits[1];
|
||||
Long exp;
|
||||
int k;
|
||||
union { ULong L[1]; float f; } u;
|
||||
#ifdef Honor_FLT_ROUNDS
|
||||
#include "gdtoa_fltrnds.h"
|
||||
#else
|
||||
#define fpi &fpi0
|
||||
#endif
|
||||
|
||||
k = __strtodg(s, sp, &fpi, &exp, bits);
|
||||
k = __strtodg(s, sp, fpi, &exp, bits);
|
||||
switch(k & STRTOG_Retmask) {
|
||||
case STRTOG_NoNumber:
|
||||
case STRTOG_Zero:
|
||||
|
@ -58,14 +58,19 @@ typedef union lD {
|
||||
|
||||
static int __strtopx (const char *s, char **sp, lD *V)
|
||||
{
|
||||
static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI };
|
||||
static FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI };
|
||||
ULong bits[2];
|
||||
Long exp;
|
||||
int k;
|
||||
UShort *L = & (V->L[0]);
|
||||
#ifdef Honor_FLT_ROUNDS
|
||||
#include "gdtoa_fltrnds.h"
|
||||
#else
|
||||
#define fpi &fpi0
|
||||
#endif
|
||||
V->D = 0.0L;
|
||||
|
||||
k = __strtodg(s, sp, &fpi, &exp, bits);
|
||||
k = __strtodg(s, sp, fpi, &exp, bits);
|
||||
switch(k & STRTOG_Retmask) {
|
||||
case STRTOG_NoNumber:
|
||||
case STRTOG_Zero:
|
||||
|
Loading…
Reference in New Issue
Block a user