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 * ld80 - long double (Intel 80 bit FP in 12 bytes) 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(_LDOUBLE ld80
, 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";
32 /* MS' long double type wants 12 bytes for Intel's 80 bit FP format.
33 * Some UNIX have sizeof(long double) == 16, yet only 80 bit are used.
34 * Assume long double uses 80 bit FP, never seen 128 bit FP. */
38 char buf
[I10_OUTPUT_MAX_PREC
+9]; /* 9 = strlen("0.e+0000") + '\0' */
41 memcpy(&ld
, &ld80
, 10);
43 TRACE("(%lf %d %x %p)\n", d
, prec
, flag
, data
);
54 memcpy(data
->str
, inf_str
, sizeof(inf_str
));
62 memcpy(data
->str
, nan_str
, sizeof(nan_str
));
68 int exp
= 1+floor(log10(d
));
76 if(prec
+1 > I10_OUTPUT_MAX_PREC
)
77 prec
= I10_OUTPUT_MAX_PREC
-1;
83 sprintf(format
, "%%.%dle", prec
);
84 sprintf(buf
, format
, d
);
87 data
->pos
= atoi(buf
+prec
+3);
91 for(p
= buf
+prec
+1; p
>buf
+1 && *p
=='0'; p
--);
94 memcpy(data
->str
, buf
+1, data
->len
);
95 data
->str
[data
->len
] = '\0';
97 if(buf
[1]!='0' && prec
-data
->len
+1>0)
98 memcpy(data
->str
+data
->len
+1, buf
+data
->len
+1, prec
-data
->len
+1);
102 #undef I10_OUTPUT_MAX_PREC