1
/* Test of lround() function.
2
$Id: lround-01.c,v 1.2.2.1 2008/03/20 21:42:30 joerg_wunsch Exp $
10
# define PRINTFLN(line, fmt, ...) \
11
printf ("\nLine %d: " fmt "\n", line, ##__VA_ARGS__)
12
# define EXIT(code) exit ((code) < 255 ? (code) : 100 + (code) % 100)
14
# if defined(__AVR_ATmega128__)
15
/* ATmega128 has enough RAM for sprintf(), print to 0x2000 in XRAM. */
16
# define PRINTFLN(line, fmt, ...) \
17
sprintf ((char *)0x2000, "\nLine %d: " fmt "\n", line, ##__VA_ARGS__)
20
# define PRINTFLN(args...)
30
/* Result is placed into SRAM variable, allocated at the start of
31
memory. This is convinient to debug: read a core dump. */
34
PROGMEM const struct { /* Table of test cases. */
35
union lofl_u x; /* argument */
43
/* A few of normal values */
47
{ { .fl= 1.49999 }, 1 },
51
{ { .fl= 1000000.5 }, 1000001 },
53
{ { .fl= -0.5 }, -1 },
54
{ { .fl= -0.9 }, -1 },
55
{ { .fl= -1.49999 }, -1 },
56
{ { .fl= -1.5 }, -2 },
57
{ { .fl= -1.9 }, -2 },
58
{ { .fl= -2.5 }, -3 },
59
{ { .fl= -1000000.5 }, -1000001 },
62
{ { 0x00000001 }, 0 },
63
{ { 0x00000100 }, 0 },
64
{ { 0x00010000 }, 0 },
65
{ { 0x007fffff }, 0 },
66
{ { 0x80000001 }, 0 },
67
{ { 0x80000100 }, 0 },
68
{ { 0x80010000 }, 0 },
69
{ { 0x807fffff }, 0 },
71
/* Margin values (positive). */
72
{ { 0x00800000 }, 0 }, /* the smallest nonzero normal */
74
{ { 0x3effffff }, 0 },
75
{ { 0x3f000000 }, 1 }, /* 0.5 */
76
{ { 0x3f000001 }, 1 },
78
{ { 0x3f7fffff }, 1 },
79
{ { 0x3f800000 }, 1 }, /* 1.0 */
80
{ { 0x3f800001 }, 1 },
82
{ { 0x3fbfffff }, 1 },
83
{ { 0x3fc00000 }, 2 }, /* 1.5 */
84
{ { 0x3fc00001 }, 2 },
86
{ { 0x401fffff }, 2 },
87
{ { 0x40200000 }, 3 }, /* 2.5 */
88
{ { 0x40200001 }, 3 },
90
{ { .fl= 0x0.fffffep+23 }, 0x7fffff },
91
{ { .fl= 0x0.ffffffp+23 }, 0x800000 },
92
{ { .fl= 0x1.000000p+23 }, 0x800000 },
94
{ { .fl= 0x0.ffffffp+31 }, 0x7fffff80 }, /* near overflow */
96
/* Margin values (negative). */
97
{ { 0x80800000 }, 0 }, /* the smallest nonzero normal */
99
{ { 0xbeffffff }, 0 },
100
{ { 0xbf000000 }, -1 }, /* -0.5 */
101
{ { 0xbf000001 }, -1 },
103
{ { 0xbf7fffff }, -1 },
104
{ { 0xbf800000 }, -1 }, /* -1.0 */
105
{ { 0xbf800001 }, -1 },
107
{ { 0xbfbfffff }, -1 },
108
{ { 0xbfc00000 }, -2 }, /* -1.5 */
109
{ { 0xbfc00001 }, -2 },
111
{ { 0xc01fffff }, -2 },
112
{ { 0xc0200000 }, -3 }, /* -2.5 */
113
{ { 0xc0200001 }, -3 },
115
{ { .fl= -0x0.fffffep+23 }, -0x7fffffL },
116
{ { .fl= -0x0.ffffffp+23 }, -0x800000L },
117
{ { .fl= -0x1.000000p+23 }, -0x800000L },
119
{ { .fl= -0x0.ffffffp+31 }, -0x7fffff80L }, /* near overflow */
120
{ { .fl= -0x1.000000p+31 }, 0x80000000L },
122
/* In addition to main(): shift 0xffffff to left . */
123
{ { .fl= 0x0.ffffffp+24 }, 0x00ffffff },
124
{ { .fl= 0x0.ffffffp+25 }, 0x01fffffe },
125
{ { .fl= 0x0.ffffffp+26 }, 0x03fffffc },
126
{ { .fl= 0x0.ffffffp+27 }, 0x07fffff8 },
127
{ { .fl= 0x0.ffffffp+28 }, 0x0ffffff0 },
128
{ { .fl= 0x0.ffffffp+29 }, 0x1fffffe0 },
129
{ { .fl= 0x0.ffffffp+30 }, 0x3fffffc0 },
130
{ { .fl= 0x0.ffffffp+31 }, 0x7fffff80 },
131
{ { .fl= -0x0.ffffffp+24 }, -0x00ffffffL },
132
{ { .fl= -0x0.ffffffp+25 }, -0x01fffffeL },
133
{ { .fl= -0x0.ffffffp+26 }, -0x03fffffcL },
134
{ { .fl= -0x0.ffffffp+27 }, -0x07fffff8L },
135
{ { .fl= -0x0.ffffffp+28 }, -0x0ffffff0L },
136
{ { .fl= -0x0.ffffffp+29 }, -0x1fffffe0L },
137
{ { .fl= -0x0.ffffffp+30 }, -0x3fffffc0L },
138
{ { .fl= -0x0.ffffffp+31 }, -0x7fffff80L },
140
/* Positive overflow */
141
{ { .fl= 0x0.800000p+32 }, 0x80000000 },
142
{ { .fl= 0x0.800001p+32 }, 0x80000000 },
143
{ { .fl= 0x0.ffffffp+32 }, 0x80000000 },
144
{ { .fl= 0x0.800000p+33 }, 0x80000000 },
145
{ { .fl= 0x0.ffffffp+33 }, 0x80000000 },
146
{ { .lo= 0x7f000000 }, 0x80000000 },
147
{ { .lo= 0x7f7fffff }, 0x80000000 },
148
{ { .lo= 0x7f800000 }, 0x80000000 }, /* +Inf */
150
/* Negative overflow */
151
{ { .fl= -0x0.800000p+32 }, 0x80000000 }, /* no overflow */
152
{ { .fl= -0x0.800001p+32 }, 0x80000000 },
153
{ { .fl= -0x0.ffffffp+32 }, 0x80000000 },
154
{ { .fl= -0x0.800000p+33 }, 0x80000000 },
155
{ { .fl= -0x0.ffffffp+33 }, 0x80000000 },
156
{ { .lo= 0xff000000 }, 0x80000000 },
157
{ { .lo= 0xff7fffff }, 0x80000000 },
158
{ { .lo= 0xff800000 }, 0x80000000 }, /* -Inf */
161
{ { 0x7f800001 }, 0x80000000 },
162
{ { 0x7fc00000 }, 0x80000000 },
163
{ { 0x7fffffff }, 0x80000000 },
164
{ { 0xff800001 }, 0x80000000 },
165
{ { 0xffc00000 }, 0x80000000 },
166
{ { 0xffffffff }, 0x80000000 },
169
void x_exit (int index)
172
fprintf (stderr, "t[%d]: %#lx\n", index - 1, v);
174
exit (index ? index : -1);
184
for (i = 0; i < (int) (sizeof(t) / sizeof(t[0])); i++) {
185
x.lo = pgm_read_dword (& t[i].x);
186
z = pgm_read_dword (& t[i].z);
192
/* Check all possible shifts. Rounding is not needed. Both signs.
196
0x0.800000p+31 --> 0x40000000 */
197
for (x.fl = 1.0, i = 0; i < 31; i++) {
199
if (v != (1L << i)) {
200
PRINTFLN (__LINE__, "i= %d v= %#lx", i, v);
204
/* Change sign to minus. */
207
if (v != -(1L << i)) {
208
PRINTFLN (__LINE__, "i= %d v= %#lx", i, v);
212
/* Change sign again and increment exponent. */
216
/* Check all possible shits with rounding.
217
0x0.c00000p+01 --> 2 1.5
218
0x0.a00000p+02 --> 3 2.5
219
0x0.900000p+03 --> 5 4.5
221
0x0.800001p+23 --> 0x400001 */
222
for (i = 1; i < 24; i++) {
224
x.lo += (0x800000 * (i-1)); /* exponent */
225
x.lo |= (0x800000 >> i); /* += 0.5 */
227
if (v != (1L << (i-1)) + 1) {
228
PRINTFLN (__LINE__, "i= %d v= %#lx", i, v);
233
/* Rounding with carry. All possible shifts to right. Both signs.
237
0x0.ffffffp+23 --> 0x800000 */
238
for (x.fl = 0x0.ffffffp+00, i = 0; i < 24; i++) {
240
if (v != (1L << i)) {
241
PRINTFLN (__LINE__, "i= %d v= %#lx", i, v);
245
/* Change sign to minus. */
248
if (v != -(1L << i)) {
249
PRINTFLN (__LINE__, "i= %d v= %#lx", i, v);
253
/* Change sign again and increment exponent. */