mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 19:55:41 +00:00
[RTL]
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:
parent
7894b5b522
commit
ef9b8f7942
2 changed files with 52 additions and 85 deletions
|
@ -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 {
|
||||||
|
struct {
|
||||||
unsigned int mantissal:32;
|
unsigned int mantissal:32;
|
||||||
unsigned int mantissah:20;
|
unsigned int mantissah:20;
|
||||||
unsigned int exponent:11;
|
unsigned int exponent:11;
|
||||||
unsigned int sign:1;
|
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':
|
||||||
|
|
|
@ -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 {
|
||||||
|
struct {
|
||||||
unsigned int mantissal:32;
|
unsigned int mantissal:32;
|
||||||
unsigned int mantissah:20;
|
unsigned int mantissah:20;
|
||||||
unsigned int exponent:11;
|
unsigned int exponent:11;
|
||||||
unsigned int sign:1;
|
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" */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue