msvcrt: Fix Inf and NaN handling in printf function.
This commit is contained in:
parent
57ed5bf32e
commit
6594212dd6
|
@ -537,6 +537,27 @@ int FUNC_NAME(pf_printf)(FUNC_NAME(puts_clbk) pf_puts, void *puts_ctx, const API
|
||||||
int len = flags.Precision + 10;
|
int len = flags.Precision + 10;
|
||||||
double val = pf_args(args_ctx, pos, VT_R8, valist).get_double;
|
double val = pf_args(args_ctx, pos, VT_R8, valist).get_double;
|
||||||
int r;
|
int r;
|
||||||
|
BOOL inf = FALSE, nan = FALSE;
|
||||||
|
|
||||||
|
if(isinf(val))
|
||||||
|
inf = TRUE;
|
||||||
|
else if(isnan(val))
|
||||||
|
nan = TRUE; /* FIXME: NaN value may be displayed as #IND or #QNAN */
|
||||||
|
|
||||||
|
if(inf || nan) {
|
||||||
|
if(nan || val<0)
|
||||||
|
flags.Sign = '-';
|
||||||
|
|
||||||
|
if(flags.Format=='g' || flags.Format=='G')
|
||||||
|
val = 1.1234; /* fraction will be overwritten with #INF or #IND string */
|
||||||
|
else
|
||||||
|
val = 1;
|
||||||
|
|
||||||
|
if(flags.Format=='a') {
|
||||||
|
if(flags.Precision==-1)
|
||||||
|
flags.Precision = 6; /* strlen("#INF00") */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(flags.Format=='f') {
|
if(flags.Format=='f') {
|
||||||
if(val>-10.0 && val<10.0)
|
if(val>-10.0 && val<10.0)
|
||||||
|
@ -566,9 +587,25 @@ int FUNC_NAME(pf_printf)(FUNC_NAME(puts_clbk) pf_puts, void *puts_ctx, const API
|
||||||
FUNC_NAME(pf_fixup_exponent)(tmp);
|
FUNC_NAME(pf_fixup_exponent)(tmp);
|
||||||
|
|
||||||
decimal_point = strchr(tmp, '.');
|
decimal_point = strchr(tmp, '.');
|
||||||
if(decimal_point)
|
if(decimal_point) {
|
||||||
*decimal_point = *locinfo->lconv->decimal_point;
|
*decimal_point = *locinfo->lconv->decimal_point;
|
||||||
|
|
||||||
|
if(inf || nan) {
|
||||||
|
static const char inf_str[] = "#INF";
|
||||||
|
static const char ind_str[] = "#IND";
|
||||||
|
|
||||||
|
for(i=1; i<=sizeof(inf ? inf_str : ind_str); i++) {
|
||||||
|
if(decimal_point[i]<'0' || decimal_point[i]>'9')
|
||||||
|
break;
|
||||||
|
|
||||||
|
decimal_point[i] = inf ? inf_str[i-1] : ind_str[i-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(i!=sizeof(inf_str) && i!=1)
|
||||||
|
decimal_point[i-1]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
len = strlen(tmp);
|
len = strlen(tmp);
|
||||||
i = FUNC_NAME(pf_fill)(pf_puts, puts_ctx, len, &flags, TRUE);
|
i = FUNC_NAME(pf_fill)(pf_puts, puts_ctx, len, &flags, TRUE);
|
||||||
if(i < 0)
|
if(i < 0)
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
|
@ -81,7 +82,7 @@ static void test_sprintf( void )
|
||||||
{
|
{
|
||||||
char buffer[100];
|
char buffer[100];
|
||||||
const char *format;
|
const char *format;
|
||||||
double pnumber=789456123;
|
double pnumber=789456123, inf, nan;
|
||||||
int x, r;
|
int x, r;
|
||||||
WCHAR wide[] = { 'w','i','d','e',0};
|
WCHAR wide[] = { 'w','i','d','e',0};
|
||||||
|
|
||||||
|
@ -639,6 +640,41 @@ static void test_sprintf( void )
|
||||||
ok(!strcmp(buffer,"123"), "failed: \"%s\"\n", buffer);
|
ok(!strcmp(buffer,"123"), "failed: \"%s\"\n", buffer);
|
||||||
r = sprintf(buffer, format, 0x12345);
|
r = sprintf(buffer, format, 0x12345);
|
||||||
ok(!strcmp(buffer,"2345"), "failed \"%s\"\n", buffer);
|
ok(!strcmp(buffer,"2345"), "failed \"%s\"\n", buffer);
|
||||||
|
|
||||||
|
nan = 0.0;
|
||||||
|
inf = 1.0/nan;
|
||||||
|
nan = sqrt(-1);
|
||||||
|
format = "%lf";
|
||||||
|
r = sprintf(buffer, format, nan);
|
||||||
|
ok(r==9, "r = %d\n", r);
|
||||||
|
ok(!strcmp(buffer, "-1.#IND00"), "failed: \"%s\"\n", buffer);
|
||||||
|
r = sprintf(buffer, format, inf);
|
||||||
|
ok(r==8, "r = %d\n", r);
|
||||||
|
ok(!strcmp(buffer, "1.#INF00"), "failed: \"%s\"\n", buffer);
|
||||||
|
|
||||||
|
format = "%le";
|
||||||
|
r = sprintf(buffer, format, nan);
|
||||||
|
ok(r==14, "r = %d\n", r);
|
||||||
|
ok(!strcmp(buffer, "-1.#IND00e+000"), "failed: \"%s\"\n", buffer);
|
||||||
|
r = sprintf(buffer, format, inf);
|
||||||
|
ok(r==13, "r = %d\n", r);
|
||||||
|
ok(!strcmp(buffer, "1.#INF00e+000"), "failed: \"%s\"\n", buffer);
|
||||||
|
|
||||||
|
format = "%lg";
|
||||||
|
r = sprintf(buffer, format, nan);
|
||||||
|
ok(r==7, "r = %d\n", r);
|
||||||
|
ok(!strcmp(buffer, "-1.#IND"), "failed: \"%s\"\n", buffer);
|
||||||
|
r = sprintf(buffer, format, inf);
|
||||||
|
ok(r==6, "r = %d\n", r);
|
||||||
|
ok(!strcmp(buffer, "1.#INF"), "failed: \"%s\"\n", buffer);
|
||||||
|
|
||||||
|
format = "%010.2lf";
|
||||||
|
r = sprintf(buffer, format, nan);
|
||||||
|
ok(r==10, "r = %d\n", r);
|
||||||
|
ok(!strcmp(buffer, "-000001.#J"), "failed: \"%s\"\n", buffer);
|
||||||
|
r = sprintf(buffer, format, inf);
|
||||||
|
ok(r==10, "r = %d\n", r);
|
||||||
|
ok(!strcmp(buffer, "0000001.#J"), "failed: \"%s\"\n", buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_swprintf( void )
|
static void test_swprintf( void )
|
||||||
|
|
Loading…
Reference in New Issue