mirror of
https://github.com/reactos/reactos.git
synced 2025-07-27 13:52:38 +00:00
sprintf:
- Implement higher precision exponent selection, checked against ecvt test cases to match wanted behavior - msvcrt printf winetests up by ~10 because current ecvt relies on non-correct behavior - Cleanup unneeded checks, wrong variable usages, add new header svn path=/trunk/; revision=42382
This commit is contained in:
parent
a1c98e143e
commit
a08bde0eb5
1 changed files with 67 additions and 38 deletions
|
@ -1,21 +1,17 @@
|
||||||
/*
|
/*
|
||||||
* PROGRAMMERS:
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* David Welch
|
* PURPOSE: CRT's vsnprintf
|
||||||
* Eric Kohl
|
* FILE: lib/sdk/crt/stdio/lnx_printf.c
|
||||||
* Gregor Schneider
|
* PROGRAMERS: David Welch
|
||||||
*
|
Eric Kohl
|
||||||
|
Gregor Schneider
|
||||||
* TODO:
|
* TODO:
|
||||||
* - Verify the implementation of '%Z'.
|
* - Verify the implementation of '%Z'.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* linux/lib/vsprintf.c
|
* Parts from linux/lib/vsprintf.c
|
||||||
*
|
* Lars Wirzenius & Linus Torvalds
|
||||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
|
|
||||||
/*
|
|
||||||
* Wirzenius wrote this portably, Torvalds fucked it up :-)
|
* Wirzenius wrote this portably, Torvalds fucked it up :-)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -156,11 +152,49 @@ typedef struct {
|
||||||
unsigned int sign:1;
|
unsigned int sign:1;
|
||||||
} ieee_double_t;
|
} ieee_double_t;
|
||||||
|
|
||||||
|
static __inline void fracrnd(double *number, int prec)
|
||||||
|
{
|
||||||
|
/* Shifts fractional digits to decimal places and compares to round table */
|
||||||
|
/* Only suitable to determine the exponent with more precision, not for normal rounding */
|
||||||
|
/* Incoming numbers are expected to range from approx -10.0 to 10.0 */
|
||||||
|
int lpos = 1, ubound, sign = 1;
|
||||||
|
long decimal = abs((long)*number);
|
||||||
|
double frac = (*number - decimal) * 10;
|
||||||
|
long rt[] =
|
||||||
|
{
|
||||||
|
0,
|
||||||
|
9,
|
||||||
|
99,
|
||||||
|
999,
|
||||||
|
9999,
|
||||||
|
99999,
|
||||||
|
999999,
|
||||||
|
9999999,
|
||||||
|
99999999,
|
||||||
|
999999999
|
||||||
|
};
|
||||||
|
|
||||||
|
if (*number < 0)
|
||||||
|
{
|
||||||
|
sign = -1;
|
||||||
|
}
|
||||||
|
ubound = min(prec, sizeof(rt)/sizeof(*rt) - 1);
|
||||||
|
while ((long)frac % 10 != 0 && lpos < ubound)
|
||||||
|
{
|
||||||
|
frac *= 10;
|
||||||
|
lpos++;
|
||||||
|
}
|
||||||
|
if (abs((long)frac) == rt[lpos])
|
||||||
|
{
|
||||||
|
*number = sign * (decimal + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
numberf(char * buf, char * end, double num, char exp_sign, int size, int precision, int type)
|
numberf(char * buf, char * end, double num, char exp_sign, int size, int precision, int type)
|
||||||
{
|
{
|
||||||
double exponent = 0.0;
|
double exponent = 0.0;
|
||||||
double e;
|
double e = 0.0;
|
||||||
long ie;
|
long ie;
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -185,9 +219,7 @@ numberf(char * buf, char * end, double num, char exp_sign, int size, int precisi
|
||||||
if ( exp_sign == 'g' || exp_sign == 'G' || exp_sign == 'e' || exp_sign == 'E' )
|
if ( exp_sign == 'g' || exp_sign == 'G' || exp_sign == 'e' || exp_sign == 'E' )
|
||||||
{
|
{
|
||||||
ie = ((unsigned int)n.n->exponent - (unsigned int)0x3ff);
|
ie = ((unsigned int)n.n->exponent - (unsigned int)0x3ff);
|
||||||
if (*n.__n == 0.0)
|
if (num != 0.0)
|
||||||
exponent = 0.0;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
exponent = ie/3.321928;
|
exponent = ie/3.321928;
|
||||||
}
|
}
|
||||||
|
@ -205,28 +237,25 @@ numberf(char * buf, char * end, double num, char exp_sign, int size, int precisi
|
||||||
|
|
||||||
if ( exp_sign == 'e' || exp_sign == 'E' )
|
if ( exp_sign == 'e' || exp_sign == 'E' )
|
||||||
{
|
{
|
||||||
|
if (num != 0.0)
|
||||||
|
{
|
||||||
|
/* Find a suitable exponent */
|
||||||
frac = modf(exponent, &e);
|
frac = modf(exponent, &e);
|
||||||
if (num < 0.0)
|
|
||||||
e--;
|
|
||||||
if (frac >= 0.5)
|
|
||||||
e++;
|
|
||||||
else if (frac < -0.5)
|
|
||||||
e--;
|
|
||||||
|
|
||||||
num2 = num/pow(10.0L, (long double)e);
|
num2 = num/pow(10.0L, (long double)e);
|
||||||
|
/* Check if rounding is possible */
|
||||||
|
fracrnd(&num2, precision);
|
||||||
if (num2 < 1.0 && num2 > -1.0)
|
if (num2 < 1.0 && num2 > -1.0)
|
||||||
{
|
{
|
||||||
e--;
|
e--;
|
||||||
num2 = num/pow(10.0L,(long double)e);
|
|
||||||
}
|
}
|
||||||
else if (num2 < -10.0 && num2 > 10.0)
|
else if (num2 <= -10.0 || num2 >= 10.0)
|
||||||
{
|
{
|
||||||
e++;
|
e++;
|
||||||
num2 = num/pow(10.0L,(long double)e);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* size-5 because "e+abc" is going to follow */
|
/* size-5 because "e+abc" is going to follow */
|
||||||
buf = numberf(buf, end, num2, 'f', size-5, precision, type);
|
buf = numberf(buf, end, num/pow(10.0L,(long double)e), 'f', size-5, precision, type);
|
||||||
isize = 4;
|
isize = 4;
|
||||||
while(*(buf-1) == ' ')
|
while(*(buf-1) == ' ')
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue