~ubuntu-branches/ubuntu/raring/avr-libc/raring-proposed

« back to all changes in this revision

Viewing changes to tests/simulate/math/lround-01.c

  • Committer: Bazaar Package Importer
  • Author(s): Hakan Ardo
  • Date: 2008-08-10 09:59:16 UTC
  • mfrom: (1.2.1 upstream) (8 intrepid)
  • mto: (4.1.7 sid)
  • mto: This revision was merged to the branch mainline in revision 9.
  • Revision ID: james.westby@ubuntu.com-20080810095916-7ku06pjsfia3hz16
Added build-depends on texlive-extra-utils (closes: #493454)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Test of lround() function.
 
2
   $Id: lround-01.c,v 1.2.2.1 2008/03/20 21:42:30 joerg_wunsch Exp $
 
3
 */
 
4
#include <math.h>
 
5
#include <stdio.h>
 
6
#include <stdlib.h>
 
7
#include "progmem.h"
 
8
 
 
9
#ifndef __AVR__
 
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)
 
13
#else
 
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__)
 
18
# else
 
19
   /* small AVR */
 
20
#  define PRINTFLN(args...)
 
21
# endif
 
22
# define EXIT   exit
 
23
#endif
 
24
 
 
25
union lofl_u {
 
26
    long lo;
 
27
    float fl;
 
28
};
 
29
 
 
30
/* Result is placed into SRAM variable, allocated at the start of
 
31
   memory. This is convinient to debug: read a core dump.       */
 
32
volatile long v = 1;
 
33
 
 
34
PROGMEM const struct {          /* Table of test cases. */
 
35
    union lofl_u x;             /* argument     */
 
36
    long z;                     /* result       */
 
37
} t[] = {
 
38
 
 
39
    /* Zero     */
 
40
    { { .fl= +0.0 },    0 },
 
41
    { { .fl= -0.0 },    0 },
 
42
    
 
43
    /* A few of normal values   */
 
44
    { { .fl= 0.1 },             0 },
 
45
    { { .fl= 0.5 },             1 },
 
46
    { { .fl= 0.9 },             1 },
 
47
    { { .fl= 1.49999 },         1 },
 
48
    { { .fl= 1.5 },             2 },
 
49
    { { .fl= 1.9 },             2 },
 
50
    { { .fl= 2.5 },             3 },
 
51
    { { .fl= 1000000.5 },       1000001 },
 
52
    { { .fl= -0.1 },            0 },
 
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 },
 
60
 
 
61
    /* Subnormal        */
 
62
    { { 0x00000001 }, 0 },
 
63
    { { 0x00000100 }, 0 },
 
64
    { { 0x00010000 }, 0 },
 
65
    { { 0x007fffff }, 0 },
 
66
    { { 0x80000001 }, 0 },
 
67
    { { 0x80000100 }, 0 },
 
68
    { { 0x80010000 }, 0 },
 
69
    { { 0x807fffff }, 0 },
 
70
    
 
71
    /* Margin values (positive).        */
 
72
    { { 0x00800000 }, 0 },              /* the smallest nonzero normal  */
 
73
 
 
74
    { { 0x3effffff }, 0 },
 
75
    { { 0x3f000000 }, 1 },              /* 0.5  */
 
76
    { { 0x3f000001 }, 1 },
 
77
 
 
78
    { { 0x3f7fffff }, 1 },
 
79
    { { 0x3f800000 }, 1 },              /* 1.0  */
 
80
    { { 0x3f800001 }, 1 },
 
81
 
 
82
    { { 0x3fbfffff }, 1 },
 
83
    { { 0x3fc00000 }, 2 },              /* 1.5  */
 
84
    { { 0x3fc00001 }, 2 },
 
85
 
 
86
    { { 0x401fffff }, 2 },
 
87
    { { 0x40200000 }, 3 },              /* 2.5  */
 
88
    { { 0x40200001 }, 3 },
 
89
 
 
90
    { { .fl= 0x0.fffffep+23 }, 0x7fffff },
 
91
    { { .fl= 0x0.ffffffp+23 }, 0x800000 },
 
92
    { { .fl= 0x1.000000p+23 }, 0x800000 },
 
93
 
 
94
    { { .fl= 0x0.ffffffp+31 }, 0x7fffff80 },    /* near overflow */
 
95
 
 
96
    /* Margin values (negative).        */
 
97
    { { 0x80800000 }, 0 },              /* the smallest nonzero normal  */
 
98
 
 
99
    { { 0xbeffffff }, 0 },
 
100
    { { 0xbf000000 }, -1 },             /* -0.5 */
 
101
    { { 0xbf000001 }, -1 },
 
102
 
 
103
    { { 0xbf7fffff }, -1 },
 
104
    { { 0xbf800000 }, -1 },             /* -1.0 */
 
105
    { { 0xbf800001 }, -1 },
 
106
 
 
107
    { { 0xbfbfffff }, -1 },
 
108
    { { 0xbfc00000 }, -2 },             /* -1.5 */
 
109
    { { 0xbfc00001 }, -2 },
 
110
 
 
111
    { { 0xc01fffff }, -2 },
 
112
    { { 0xc0200000 }, -3 },             /* -2.5 */
 
113
    { { 0xc0200001 }, -3 },
 
114
 
 
115
    { { .fl= -0x0.fffffep+23 }, -0x7fffffL },
 
116
    { { .fl= -0x0.ffffffp+23 }, -0x800000L },
 
117
    { { .fl= -0x1.000000p+23 }, -0x800000L },
 
118
 
 
119
    { { .fl= -0x0.ffffffp+31 }, -0x7fffff80L }, /* near overflow */
 
120
    { { .fl= -0x1.000000p+31 }, 0x80000000L },
 
121
 
 
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 },
 
139
 
 
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 */
 
149
 
 
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 */
 
159
 
 
160
    /* NaN      */
 
161
    { { 0x7f800001 },   0x80000000 },
 
162
    { { 0x7fc00000 },   0x80000000 },
 
163
    { { 0x7fffffff },   0x80000000 },
 
164
    { { 0xff800001 },   0x80000000 },
 
165
    { { 0xffc00000 },   0x80000000 },
 
166
    { { 0xffffffff },   0x80000000 },
 
167
};
 
168
 
 
169
void x_exit (int index)
 
170
{
 
171
#ifndef __AVR__
 
172
    fprintf (stderr, "t[%d]:  %#lx\n", index - 1, v);
 
173
#endif
 
174
    exit (index ? index : -1);
 
175
}
 
176
 
 
177
int main ()
 
178
{
 
179
    union lofl_u x;
 
180
    long z;
 
181
    int i;
 
182
 
 
183
    /* Table.   */    
 
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);
 
187
        v = lround (x.fl);
 
188
        if (v != z)
 
189
            x_exit (i+1);
 
190
    }
 
191
 
 
192
    /* Check all possible shifts. Rounding is not needed. Both signs.
 
193
       0x0.800000p+01 --> 1
 
194
       0x0.800000p+02 --> 2
 
195
       ...
 
196
       0x0.800000p+31 --> 0x40000000    */
 
197
    for (x.fl = 1.0, i = 0; i < 31; i++) {
 
198
        v = lround (x.fl);
 
199
        if (v != (1L << i)) {
 
200
            PRINTFLN (__LINE__, "i= %d  v= %#lx", i, v);
 
201
            EXIT (100 + i);
 
202
        }
 
203
 
 
204
        /* Change sign to minus.        */
 
205
        x.lo |= 0x80000000;
 
206
        v = lround (x.fl);
 
207
        if (v != -(1L << i)) {
 
208
            PRINTFLN (__LINE__, "i= %d  v= %#lx", i, v);
 
209
            EXIT (200 + i);
 
210
        }
 
211
 
 
212
        /* Change sign again and increment exponent.    */
 
213
        x.lo += 0x80800000;
 
214
    }
 
215
 
 
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
 
220
       ...
 
221
       0x0.800001p+23 --> 0x400001      */
 
222
    for (i = 1; i < 24; i++) {
 
223
        x.fl = 1.0;
 
224
        x.lo += (0x800000 * (i-1));     /* exponent     */
 
225
        x.lo |= (0x800000 >> i);        /* += 0.5       */
 
226
        v = lround (x.fl);
 
227
        if (v != (1L << (i-1)) + 1) {
 
228
            PRINTFLN (__LINE__, "i= %d  v= %#lx", i, v);
 
229
            EXIT (300 + i);
 
230
        }
 
231
    }
 
232
 
 
233
    /* Rounding with carry. All possible shifts to right. Both signs.
 
234
       0x0.ffffffp+00 --> 1
 
235
       0x0.ffffffp+01 --> 2
 
236
       ...
 
237
       0x0.ffffffp+23 --> 0x800000      */
 
238
    for (x.fl = 0x0.ffffffp+00, i = 0; i < 24; i++) {
 
239
        v = lround (x.fl);
 
240
        if (v != (1L << i)) {
 
241
            PRINTFLN (__LINE__, "i= %d  v= %#lx", i, v);
 
242
            EXIT (400 + i);
 
243
        }
 
244
 
 
245
        /* Change sign to minus.        */
 
246
        x.lo |= 0x80000000;
 
247
        v = lround (x.fl);
 
248
        if (v != -(1L << i)) {
 
249
            PRINTFLN (__LINE__, "i= %d  v= %#lx", i, v);
 
250
            EXIT (500 + i);
 
251
        }
 
252
 
 
253
        /* Change sign again and increment exponent.    */
 
254
        x.lo += 0x80800000;
 
255
    }
 
256
 
 
257
    return 0;
 
258
}