3 #define I10_OUTPUT_MAX_PREC 21
4 /* Internal structure used by $I10_OUTPUT */
5 struct _I10_OUTPUT_DATA
{
9 char str
[I10_OUTPUT_MAX_PREC
+1]; /* add space for '\0' */
12 /*********************************************************************
13 * $I10_OUTPUT (MSVCRT.@)
14 * ld - long double to be printed to data
15 * prec - precision of part, we're interested in
16 * flag - 0 for first prec digits, 1 for fractional part
17 * data - data to be populated
20 * 0 if given double is NaN or INF
24 * Native sets last byte of data->str to '0' or '9', I don't know what
25 * it means. Current implementation sets it always to '0'.
27 int CDECL
MSVCRT_I10_OUTPUT(long double ld
, int prec
, int flag
, struct _I10_OUTPUT_DATA
*data
)
29 static const char inf_str
[] = "1#INF";
30 static const char nan_str
[] = "1#QNAN";
34 char buf
[I10_OUTPUT_MAX_PREC
+9]; /* 9 = strlen("0.e+0000") + '\0' */
37 TRACE("(%lf %d %x %p)\n", d
, prec
, flag
, data
);
48 memcpy(data
->str
, inf_str
, sizeof(inf_str
));
56 memcpy(data
->str
, nan_str
, sizeof(nan_str
));
62 int exp
= 1+floor(log10(d
));
70 if(prec
+1 > I10_OUTPUT_MAX_PREC
)
71 prec
= I10_OUTPUT_MAX_PREC
-1;
77 sprintf(format
, "%%.%dle", prec
);
78 sprintf(buf
, format
, d
);
81 data
->pos
= atoi(buf
+prec
+3);
85 for(p
= buf
+prec
+1; p
>buf
+1 && *p
=='0'; p
--);
88 memcpy(data
->str
, buf
+1, data
->len
);
89 data
->str
[data
->len
] = '\0';
91 if(buf
[1]!='0' && prec
-data
->len
+1>0)
92 memcpy(data
->str
+data
->len
+1, buf
+data
->len
+1, prec
-data
->len
+1);
96 #undef I10_OUTPUT_MAX_PREC