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:
Ozkan Sezer 2009-04-15 09:53:14 +00:00
parent b49043572b
commit fef98cff07
9 changed files with 82 additions and 18 deletions

View File

@ -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,

View File

@ -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 ".").

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View 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;
}

View File

@ -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))

View File

@ -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:

View File

@ -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: