1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
/* Float tests.
operation: ADD, SUB, MUL, DIV, REVDIV
*/
#if 1
// we are in the regression tests
#include <testfwk.h>
#define DEBUG(x)
#define {operation} 1
#else
// we are standalone
#include <stdio.h>
#define DEBUG(x) x
#define ASSERT(x)
#define ADD 1
#define SUB 1
#define MUL 1
#define DIV 1
#define REVDIV 1
#endif
#ifdef __SDCC_mcs51
# define STORAGE __xdata
# define XDATA __xdata
#elif __SDCC_pic16
# define STORAGE __code
# define XDATA
#else
# define STORAGE
# define XDATA
#endif
#if !defined(__SDCC_pdk14) && !defined(__SDCC_pdk15) // Lack of memory
XDATA volatile float left, right, result;
struct {
float left, right, add, sub, mul, div, revdiv;
} STORAGE cases[]={
// left right add sub mul div revdiv
{ 12.8, 25.6, 38.4, -12.8, 327.68, 0.5, 2},
{ 12.8, -25.6, -12.8, 38.4, -327.68, -0.5, -2},
{ -12.8, 25.6, 12.8, -38.4, -327.68, -0.5, -2},
{ -12.8, -25.6, -38.4, 12.8, 327.68, 0.5, 2},
{ 100.0, 10.0, 110.0, 90.0, 1000.00, 10.0, 0.1},
{ 1000.0, 10.0, 1010.0, 990.0, 10000.00, 100.0, 0.01},
{ 10000.0, 10.0, 10010.0, 9990.0, 100000.00, 1000.0, 0.001},
{ 100000.0, 10.0, 100010.0, 99990.0, 1000000.00, 10000.0, 0.0001},
{ 1000000.0, 10.0, 1000010.0, 999990.0, 10000000.00, 100000.0, 0.00001},
{10000000.0, 10.0,10000010.0, 9999990.0,100000000.00, 1000000.0, 0.000001},
{ 0x100, 0x10, 0x110, 0xf0, 0x1000, 0x10, 0.0625},
{ 0x1000, 0x10, 0x1010, 0xff0, 0x10000, 0x100, 0.00390625},
{ 0x10000, 0x10, 0x10010, 0xfff0, 0x100000, 0x1000, 0.00024414},
{ 0x100000, 0x10, 0x100010, 0xffff0, 0x1000000, 0x10000, 0 /* ignore */},
{ 0x1000000, 0x10, 0x1000010, 0xfffff0, 0x10000000, 0x100000, 0 /* ignore */},
{0x10000000, 0x10,0x10000010, 0xffffff0, (float)0x10000000*0x10,
0x1000000, 0 /* ignore */},
};
XDATA int tests = 0, errors = 0;
char
compare (float is, float should)
{
float diff = should ? is / should : 0;
tests++;
DEBUG (printf (" %1.3f (%f %f) ", is, should, diff));
if (should == 0)
{
DEBUG (printf ("IGNORED!\n"));
return 0;
}
// skip the fp roundoff errors
if (diff > 0.999999 && diff < 1.00001)
{
DEBUG (printf ("OK!\n"));
ASSERT (1);
return 0;
}
else
{
errors++;
DEBUG (printf ("FAIL!\n"));
ASSERT (0);
return 1;
}
}
#endif
void
testFloatMath (void)
{
#if !defined(__SDCC_pdk14) && !defined(__SDCC_pdk15) // Lack of memory
int i;
int t = sizeof (cases) / sizeof (cases[0]);
float result;
for (i = 0; i < t; i++)
{
DEBUG (printf ("Case %d ", i));
#ifdef ADD
// add
result = cases[i].left + cases[i].right;
DEBUG (printf ("%1.3f + %1.3f =", cases[i].left, cases[i].right));
compare (result, cases[i].add);
#endif
#ifdef SUB
// sub
result = cases[i].left - cases[i].right;
DEBUG (printf ("%1.3f - %1.3f =", cases[i].left, cases[i].right));
compare (result, cases[i].sub);
#endif
#ifdef MUL
// mul
result = cases[i].left * cases[i].right;
DEBUG (printf ("%1.3f * %1.3f =", cases[i].left, cases[i].right));
compare (result, cases[i].mul);
#endif
#ifdef DIV
// div
result = cases[i].left / cases[i].right;
DEBUG (printf ("%1.3f / %1.3f =", cases[i].left, cases[i].right));
compare (result, cases[i].div);
#endif
#ifdef REVDIV
// revdiv
result = cases[i].right / cases[i].left;
DEBUG (printf ("%1.3f / %1.3f =", cases[i].right, cases[i].left));
compare(result, cases[i].revdiv);
#endif
}
DEBUG (printf ("%d tests, %d errors\n", tests, errors));
#endif
}
void
testFloatMulRound (void)
{
#if !defined(__SDCC_pdk14) && !defined(__SDCC_pdk15) // Lack of memory
right = 2.0 / 10.61;
result = 10.61 * right;
compare (result, 2.0);
#endif
}
#if 0
void
main (void)
{
testFloatMath ();
testFloatMulRound ();
}
#endif
|