Patch by Stefan Ginsberg:
Don't use double in rtl's sprintf / swprintf, use double_t union instead. Minor modifications by me.

svn path=/branches/ros-amd64-bringup/; revision=44968
This commit is contained in:
Timo Kreuzer 2010-01-05 23:02:08 +00:00
parent 7894b5b522
commit ef9b8f7942
2 changed files with 52 additions and 85 deletions

View file

@ -27,43 +27,35 @@
#define SPECIAL 32 /* 0x */ #define SPECIAL 32 /* 0x */
#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
#define REMOVEHEX 256 /* use 256 as remve 0x frim BASE 16 */ #define REMOVEHEX 256 /* use 256 as remve 0x frim BASE 16 */
typedef struct { typedef union {
unsigned int mantissal:32; struct {
unsigned int mantissah:20; unsigned int mantissal:32;
unsigned int exponent:11; unsigned int mantissah:20;
unsigned int sign:1; unsigned int exponent:11;
unsigned int sign:1;
};
long long AsLongLong;
} double_t; } double_t;
#if 0 /* We depend on this being true */
C_ASSERT(sizeof(double_t) == sizeof(double));
static static
__inline __inline
int int
_isinf(double __x) _isinf(double_t x)
{ {
union return ( x.exponent == 0x7ff && ( x.mantissah == 0 && x.mantissal == 0 ));
{
double* __x;
double_t* x;
} x;
x.__x = &__x;
return ( x.x->exponent == 0x7ff && ( x.x->mantissah == 0 && x.x->mantissal == 0 ));
} }
static static
__inline __inline
int int
_isnan(double __x) _isnan(double_t x)
{ {
union return ( x.exponent == 0x7ff && ( x.mantissah != 0 || x.mantissal != 0 ));
{
double* __x;
double_t* x;
} x;
x.__x = &__x;
return ( x.x->exponent == 0x7ff && ( x.x->mantissah != 0 || x.x->mantissal != 0 ));
} }
#endif
static static
__inline __inline
@ -180,16 +172,14 @@ number(char * buf, char * end, long long num, int base, int size, int precision,
return buf; return buf;
} }
#if 0
static char * static char *
numberf(char * buf, char * end, double num, int base, int size, int precision, int type) numberf(char * buf, char * end, double_t num, int base, int size, int precision, int type)
{ {
char c,sign,tmp[66]; char c,sign,tmp[66];
const char *digits; const char *digits;
const char *small_digits = "0123456789abcdefghijklmnopqrstuvwxyz"; const char *small_digits = "0123456789abcdefghijklmnopqrstuvwxyz";
const char *large_digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; const char *large_digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int i; int i;
long long x;
/* FIXME /* FIXME
the float version of number is direcly copy of number the float version of number is direcly copy of number
@ -203,9 +193,9 @@ numberf(char * buf, char * end, double num, int base, int size, int precision, i
c = (type & ZEROPAD) ? '0' : ' '; c = (type & ZEROPAD) ? '0' : ' ';
sign = 0; sign = 0;
if (type & SIGN) { if (type & SIGN) {
if (num < 0) { if (num.sign) {
sign = '-'; sign = '-';
num = -num; num.sign = 0;
size--; size--;
} else if (type & PLUS) { } else if (type & PLUS) {
sign = '+'; sign = '+';
@ -222,15 +212,11 @@ numberf(char * buf, char * end, double num, int base, int size, int precision, i
size--; size--;
} }
i = 0; i = 0;
if (num == 0) if (num.AsLongLong == 0)
tmp[i++] = '0'; tmp[i++] = '0';
else while (num != 0) else while (num.AsLongLong != 0)
{ {
x = num; tmp[i++] = digits[do_div(&num.AsLongLong,base)];
tmp[i++] = digits[do_div(&x,base)];
#ifndef _M_ARM // Missing __floatdidf in CeGCC 0.55 -- GCC 4.4
num=x;
#endif
} }
if (i > precision) if (i > precision)
precision = i; precision = i;
@ -285,7 +271,6 @@ numberf(char * buf, char * end, double num, int base, int size, int precision, i
} }
return buf; return buf;
} }
#endif
static char* static char*
string(char* buf, char* end, const char* s, int len, int field_width, int precision, int flags) string(char* buf, char* end, const char* s, int len, int field_width, int precision, int flags)
@ -392,7 +377,7 @@ int __cdecl _vsnprintf(char *buf, size_t cnt, const char *fmt, va_list args)
{ {
int len; int len;
unsigned long long num; unsigned long long num;
// double _double; double_t _double;
int base; int base;
char *str, *end; char *str, *end;
@ -597,14 +582,13 @@ int __cdecl _vsnprintf(char *buf, size_t cnt, const char *fmt, va_list args)
} }
continue; continue;
#if 0
/* float number formats - set up the flags and "break" */ /* float number formats - set up the flags and "break" */
case 'e': case 'e':
case 'E': case 'E':
case 'f': case 'f':
case 'g': case 'g':
case 'G': case 'G':
_double = (double)va_arg(args, double); _double = va_arg(args, double_t);
if ( _isnan(_double) ) { if ( _isnan(_double) ) {
s = "Nan"; s = "Nan";
len = 3; len = 3;
@ -635,11 +619,11 @@ int __cdecl _vsnprintf(char *buf, size_t cnt, const char *fmt, va_list args)
} else { } else {
if ( precision == -1 ) if ( precision == -1 )
precision = 6; precision = 6;
str = numberf(str, end, (int)_double, base, field_width, precision, flags); str = numberf(str, end, _double, base, field_width, precision, flags);
} }
continue; continue;
#endif
/* integer number formats - set up the flags and "break" */ /* integer number formats - set up the flags and "break" */
case 'o': case 'o':

View file

@ -27,42 +27,35 @@
#define SPECIAL 32 /* 0x */ #define SPECIAL 32 /* 0x */
#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
#define REMOVEHEX 256 /* use 256 as remve 0x frim BASE 16 */ #define REMOVEHEX 256 /* use 256 as remve 0x frim BASE 16 */
typedef struct { typedef union {
unsigned int mantissal:32; struct {
unsigned int mantissah:20; unsigned int mantissal:32;
unsigned int exponent:11; unsigned int mantissah:20;
unsigned int sign:1; unsigned int exponent:11;
unsigned int sign:1;
};
long long AsLongLong;
} double_t; } double_t;
#if 0
/* We depend on this being true */
C_ASSERT(sizeof(double_t) == sizeof(double));
static static
__inline __inline
int int
_isinf(double __x) _isinf(double_t x)
{ {
union return ( x.exponent == 0x7ff && ( x.mantissah == 0 && x.mantissal == 0 ));
{
double* __x;
double_t* x;
} x;
x.__x = &__x;
return ( x.x->exponent == 0x7ff && ( x.x->mantissah == 0 && x.x->mantissal == 0 ));
} }
static static
__inline __inline
int int
_isnan(double __x) _isnan(double_t x)
{ {
union return ( x.exponent == 0x7ff && ( x.mantissah != 0 || x.mantissal != 0 ));
{
double* __x;
double_t* x;
} x;
x.__x = &__x;
return ( x.x->exponent == 0x7ff && ( x.x->mantissah != 0 || x.x->mantissal != 0 ));
} }
#endif
static static
__inline __inline
@ -178,16 +171,14 @@ number(wchar_t * buf, wchar_t * end, long long num, int base, int size, int prec
return buf; return buf;
} }
#if 0
static wchar_t * static wchar_t *
numberf(wchar_t * buf, wchar_t * end, double num, int base, int size, int precision, int type) numberf(wchar_t * buf, wchar_t * end, double_t num, int base, int size, int precision, int type)
{ {
wchar_t c, sign, tmp[66]; wchar_t c, sign, tmp[66];
const wchar_t *digits; const wchar_t *digits;
const wchar_t *small_digits = L"0123456789abcdefghijklmnopqrstuvwxyz"; const wchar_t *small_digits = L"0123456789abcdefghijklmnopqrstuvwxyz";
const wchar_t *large_digits = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; const wchar_t *large_digits = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int i; int i;
long long x;
/* FIXME /* FIXME
the float version of number is direcly copy of number the float version of number is direcly copy of number
@ -202,9 +193,9 @@ numberf(wchar_t * buf, wchar_t * end, double num, int base, int size, int precis
c = (type & ZEROPAD) ? L'0' : L' '; c = (type & ZEROPAD) ? L'0' : L' ';
sign = 0; sign = 0;
if (type & SIGN) { if (type & SIGN) {
if (num < 0) { if (num.sign) {
sign = L'-'; sign = L'-';
num = -num; num.sign = 0;
size--; size--;
} else if (type & PLUS) { } else if (type & PLUS) {
sign = L'+'; sign = L'+';
@ -221,15 +212,11 @@ numberf(wchar_t * buf, wchar_t * end, double num, int base, int size, int precis
size--; size--;
} }
i = 0; i = 0;
if (num == 0) if (num.AsLongLong == 0)
tmp[i++] = L'0'; tmp[i++] = L'0';
else while (num != 0) else while (num.AsLongLong != 0)
{ {
x = num; tmp[i++] = digits[do_div(&num.AsLongLong,base)];
tmp[i++] = digits[do_div(&x,base)];
#ifndef _M_ARM // Missing __floatdidf in CeGCC 0.55 -- GCC 4.4
num = x;
#endif
} }
if (i > precision) if (i > precision)
precision = i; precision = i;
@ -284,7 +271,6 @@ numberf(wchar_t * buf, wchar_t * end, double num, int base, int size, int precis
} }
return buf; return buf;
} }
#endif
static wchar_t* static wchar_t*
string(wchar_t* buf, wchar_t* end, const char* s, int len, int field_width, int precision, int flags) string(wchar_t* buf, wchar_t* end, const char* s, int len, int field_width, int precision, int flags)
@ -395,10 +381,8 @@ int __cdecl _vsnwprintf(wchar_t *buf, size_t cnt, const wchar_t *fmt, va_list ar
wchar_t * str, * end; wchar_t * str, * end;
const char *s; const char *s;
const wchar_t *sw; const wchar_t *sw;
#if 0
const wchar_t *ss; const wchar_t *ss;
double _double; double_t _double;
#endif
int flags; /* flags to number() */ int flags; /* flags to number() */
@ -595,14 +579,13 @@ int __cdecl _vsnwprintf(wchar_t *buf, size_t cnt, const wchar_t *fmt, va_list ar
*ip = (str - buf); *ip = (str - buf);
} }
continue; continue;
#if 0
/* float number formats - set up the flags and "break" */ /* float number formats - set up the flags and "break" */
case 'e': case 'e':
case 'E': case 'E':
case 'f': case 'f':
case 'g': case 'g':
case 'G': case 'G':
_double = (double)va_arg(args, double); _double = va_arg(args, double_t);
if ( _isnan(_double) ) { if ( _isnan(_double) ) {
ss = L"Nan"; ss = L"Nan";
@ -638,7 +621,7 @@ int __cdecl _vsnwprintf(wchar_t *buf, size_t cnt, const wchar_t *fmt, va_list ar
} }
continue; continue;
#endif
/* integer number formats - set up the flags and "break" */ /* integer number formats - set up the flags and "break" */