ReactOS 0.4.16-dev-109-gf4cb10f
i10output.c File Reference
#include <precomp.h>
Include dependency graph for i10output.c:

Go to the source code of this file.

Classes

struct  MSVCRT__LDOUBLE
 
struct  fpnum
 
struct  _I10_OUTPUT_DATA
 

Macros

#define EXP_BITS   11
 
#define MANT_BITS   53
 
#define I10_OUTPUT_MAX_PREC   21
 

Enumerations

enum  fpmod {
  FP_ROUND_ZERO , FP_ROUND_DOWN , FP_ROUND_EVEN , FP_ROUND_UP ,
  FP_VAL_INFINITY , FP_VAL_NAN
}
 

Functions

int fpnum_double (struct fpnum *fp, double *d)
 
int CDECL I10_OUTPUT (MSVCRT__LDOUBLE ld80, int prec, int flag, struct _I10_OUTPUT_DATA *data)
 

Macro Definition Documentation

◆ EXP_BITS

#define EXP_BITS   11

Definition at line 21 of file i10output.c.

◆ I10_OUTPUT_MAX_PREC

#define I10_OUTPUT_MAX_PREC   21

Definition at line 138 of file i10output.c.

◆ MANT_BITS

#define MANT_BITS   53

Definition at line 22 of file i10output.c.

Enumeration Type Documentation

◆ fpmod

Enumerator
FP_ROUND_ZERO 
FP_ROUND_DOWN 
FP_ROUND_EVEN 
FP_ROUND_UP 
FP_VAL_INFINITY 
FP_VAL_NAN 

Definition at line 5 of file i10output.c.

5 {
6 FP_ROUND_ZERO, /* only used when dropped part contains only zeros */
12};
@ FP_VAL_NAN
Definition: i10output.c:11
@ FP_ROUND_EVEN
Definition: i10output.c:8
@ FP_VAL_INFINITY
Definition: i10output.c:10
@ FP_ROUND_UP
Definition: i10output.c:9
@ FP_ROUND_ZERO
Definition: i10output.c:6
@ FP_ROUND_DOWN
Definition: i10output.c:7

Function Documentation

◆ fpnum_double()

int fpnum_double ( struct fpnum fp,
double d 
)

Definition at line 24 of file i10output.c.

25{
26 ULONGLONG bits = 0;
27
28 if (fp->mod == FP_VAL_INFINITY)
29 {
30 *d = fp->sign * INFINITY;
31 return 0;
32 }
33
34 if (fp->mod == FP_VAL_NAN)
35 {
36 bits = ~0;
37 if (fp->sign == 1)
38 bits &= ~((ULONGLONG)1 << (MANT_BITS + EXP_BITS - 1));
39 *d = *(double*)&bits;
40 return 0;
41 }
42
43 TRACE("%c %#I64x *2^%d (round %d)\n", fp->sign == -1 ? '-' : '+',
44 fp->m, fp->exp, fp->mod);
45 if (!fp->m)
46 {
47 *d = fp->sign * 0.0;
48 return 0;
49 }
50
51 /* make sure that we don't overflow modifying exponent */
52 if (fp->exp > 1<<EXP_BITS)
53 {
54 *d = fp->sign * INFINITY;
55 return ERANGE;
56 }
57 if (fp->exp < -(1<<EXP_BITS))
58 {
59 *d = fp->sign * 0.0;
60 return ERANGE;
61 }
62 fp->exp += MANT_BITS - 1;
63
64 /* normalize mantissa */
65 while(fp->m < (ULONGLONG)1 << (MANT_BITS-1))
66 {
67 fp->m <<= 1;
68 fp->exp--;
69 }
70 while(fp->m >= (ULONGLONG)1 << MANT_BITS)
71 {
72 if (fp->m & 1 || fp->mod != FP_ROUND_ZERO)
73 {
74 if (!(fp->m & 1)) fp->mod = FP_ROUND_DOWN;
75 else if(fp->mod == FP_ROUND_ZERO) fp->mod = FP_ROUND_EVEN;
76 else fp->mod = FP_ROUND_UP;
77 }
78 fp->m >>= 1;
79 fp->exp++;
80 }
81 fp->exp += (1 << (EXP_BITS-1)) - 1;
82
83 /* handle subnormals */
84 if (fp->exp <= 0)
85 {
86 if (fp->m & 1 && fp->mod == FP_ROUND_ZERO) fp->mod = FP_ROUND_EVEN;
87 else if (fp->m & 1) fp->mod = FP_ROUND_UP;
88 else if (fp->mod != FP_ROUND_ZERO) fp->mod = FP_ROUND_DOWN;
89 fp->m >>= 1;
90 }
91 while(fp->m && fp->exp<0)
92 {
93 if (fp->m & 1 && fp->mod == FP_ROUND_ZERO) fp->mod = FP_ROUND_EVEN;
94 else if (fp->m & 1) fp->mod = FP_ROUND_UP;
95 else if (fp->mod != FP_ROUND_ZERO) fp->mod = FP_ROUND_DOWN;
96 fp->m >>= 1;
97 fp->exp++;
98 }
99
100 /* round mantissa */
101 if (fp->mod == FP_ROUND_UP || (fp->mod == FP_ROUND_EVEN && fp->m & 1))
102 {
103 fp->m++;
104
105 /* handle subnormal that falls into regular range due to rounding */
106 if (fp->m == (ULONGLONG)1 << (MANT_BITS - 1))
107 {
108 fp->exp++;
109 }
110 else if (fp->m >= (ULONGLONG)1 << MANT_BITS)
111 {
112 fp->exp++;
113 fp->m >>= 1;
114 }
115 }
116
117 if (fp->exp >= (1<<EXP_BITS)-1)
118 {
119 *d = fp->sign * INFINITY;
120 return ERANGE;
121 }
122 if (!fp->m || fp->exp < 0)
123 {
124 *d = fp->sign * 0.0;
125 return ERANGE;
126 }
127
128 if (fp->sign == -1)
129 bits |= (ULONGLONG)1 << (MANT_BITS + EXP_BITS - 1);
130 bits |= (ULONGLONG)fp->exp << (MANT_BITS - 1);
131 bits |= fp->m & (((ULONGLONG)1 << (MANT_BITS - 1)) - 1);
132
133 TRACE("returning %#I64x\n", bits);
134 *d = *(double*)&bits;
135 return 0;
136}
#define ERANGE
Definition: acclib.h:92
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:10929
#define EXP_BITS
Definition: i10output.c:21
#define MANT_BITS
Definition: i10output.c:22
#define d
Definition: ke_i.h:81
#define INFINITY
Definition: misc.c:36
#define TRACE(s)
Definition: solgame.cpp:4
enum fpmod mod
Definition: i10output.c:17
ULONGLONG m
Definition: i10output.c:16
int exp
Definition: i10output.c:15
int sign
Definition: i10output.c:14
uint64_t ULONGLONG
Definition: typedefs.h:67

Referenced by I10_OUTPUT().

◆ I10_OUTPUT()

int CDECL I10_OUTPUT ( MSVCRT__LDOUBLE  ld80,
int  prec,
int  flag,
struct _I10_OUTPUT_DATA data 
)

Definition at line 162 of file i10output.c.

163{
164 struct fpnum num;
165 double d;
166 char format[8];
167 char buf[I10_OUTPUT_MAX_PREC+9]; /* 9 = strlen("0.e+0000") + '\0' */
168 char *p;
169
170 if ((ld80.x80[2] & 0x7fff) == 0x7fff)
171 {
172 if (ld80.x80[0] == 0 && ld80.x80[1] == 0x80000000)
173 strcpy( data->str, "1#INF" );
174 else
175 strcpy( data->str, (ld80.x80[1] & 0x40000000) ? "1#QNAN" : "1#SNAN" );
176 data->pos = 1;
177 data->sign = (ld80.x80[2] & 0x8000) ? '-' : ' ';
178 data->len = (BYTE)strlen(data->str);
179 return 0;
180 }
181
182 num.sign = (ld80.x80[2] & 0x8000) ? -1 : 1;
183 num.exp = (ld80.x80[2] & 0x7fff) - 0x3fff - 63;
184 num.m = ld80.x80[0] | ((ULONGLONG)ld80.x80[1] << 32);
185 num.mod = FP_ROUND_EVEN;
186 fpnum_double( &num, &d );
187 TRACE("(%lf %d %x %p)\n", d, prec, flag, data);
188
189 if(d<0) {
190 data->sign = '-';
191 d = -d;
192 } else
193 data->sign = ' ';
194
195 if(flag&1) {
196 int exp = 1 + floor(log10(d));
197
198 prec += exp;
199 if(exp < 0)
200 prec--;
201 }
202 prec--;
203
204 if(prec+1 > I10_OUTPUT_MAX_PREC)
205 prec = I10_OUTPUT_MAX_PREC-1;
206 else if(prec < 0) {
207 d = 0.0;
208 prec = 0;
209 }
210
211 sprintf_s(format, sizeof(format), "%%.%dle", prec);
212 sprintf_s(buf, sizeof(buf), format, d);
213
214 buf[1] = buf[0];
215 data->pos = atoi(buf+prec+3);
216 if(buf[1] != '0')
217 data->pos++;
218
219 for(p = buf+prec+1; p>buf+1 && *p=='0'; p--);
220 data->len = p-buf;
221
222 memcpy(data->str, buf+1, data->len);
223 data->str[data->len] = '\0';
224
225 if(buf[1]!='0' && prec-data->len+1>0)
226 memcpy(data->str+data->len+1, buf+data->len+1, prec-data->len+1);
227
228 return 1;
229}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
double log10(double x)
Definition: freeldr.c:125
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLfloat GLfloat p
Definition: glext.h:8902
GLuint GLuint num
Definition: glext.h:9618
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean flag
Definition: glfuncs.h:52
int fpnum_double(struct fpnum *fp, double *d)
Definition: i10output.c:24
#define I10_OUTPUT_MAX_PREC
Definition: i10output.c:138
_Check_return_ _CRTIMP double __cdecl floor(_In_ double x)
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
DWORD exp
Definition: msg.c:16058
ULONG x80[3]
Definition: msvcrt.h:91
Definition: format.c:58
unsigned char BYTE
Definition: xxhash.c:193