Added very useful and convenient macro for parsing attribute IDs
[AROS.git] / test / mathtest.c
blob7f0ec0f7b1bbc972f28492d21e6430e2d20349dd
1 #include <string.h>
3 #include <aros/asmcall.h>
5 #include <proto/alib.h>
7 #include <proto/exec.h>
8 #include <proto/aros.h>
9 #include <proto/dos.h>
11 double X_Mul(double x, double y)
13 if (x==x) return x*y;
14 return x*y;
17 /* to avoid casts these two lines are absolutely necessary!!*/
18 #define float LONG
20 #include <proto/mathffp.h>
21 #include <proto/mathtrans.h>
22 #include <proto/mathieeesingbas.h>
23 #include <proto/mathieeesingtrans.h>
24 #include <proto/mathieeedoubbas.h>
25 #include <proto/mathieeedoubtrans.h>
27 #include <exec/types.h>
29 struct Library * MathBase;
30 struct Library * MathTransBase;
31 struct Library * MathIeeeSingBasBase;
32 struct Library * MathIeeeSingTransBase;
33 struct Library * MathIeeeDoubBasBase;
34 struct Library * MathIeeeDoubTransBase;
36 #ifdef __mc68000
37 /* For compatability with AOS, our test reference,
38 * use this SPrintf()
40 static AROS_UFH2(VOID, _SPutC,
41 AROS_UFHA(BYTE, c, D0),
42 AROS_UFHA(BYTE **, ptr, A3))
44 AROS_USERFUNC_INIT
46 if (c != 0)
47 Write(Output(),&c,1);
49 AROS_USERFUNC_EXIT
52 #undef Printf
53 VOID Printf( const char *format, ...)
55 RawDoFmt( format, (APTR)&(((ULONG *)&format)[1]), _SPutC, NULL);
57 #endif
59 int main(int argc, char **argv)
61 LONG tested = 0, passed = 0;
62 float FFPOne, FFPTwo, FFPOnehalf, FFPMinusOne, FFPNull;
63 float SPOne, SPTwo, SPOnehalf;
64 float float_res;
65 LONG * float_resptr = (LONG *)&float_res;
66 LONG * ptr;
67 LONG wanted;
68 double double_res, double_res2;
69 double * Darg1;
70 QUAD * double_resptr = (QUAD *)&double_res;
71 QUAD * double_resptr2 = (QUAD *)&double_res2;
72 QUAD QArg1;
74 Darg1 = (double *)&QArg1;
76 #define DEF_FFPOne 0x80000041UL
77 #define DEF_FFPTwo 0x80000042UL
78 #define DEF_FFPMinusOne 0x800000C1UL
79 #define DEF_FFPOnehalf 0x80000040UL
80 #define DEF_FFPNull 0x00000000UL
82 #define DEF_SPOne 0x3f800000UL
83 #define DEF_SPTwo 0x40000000UL
84 #define DEF_SPOnehalf 0x3f000000UL
86 #define DEF_DPOne 0x3ff0000000000000ULL
87 #define DEF_DPMinusOne 0xbff0000000000000ULL
88 #define DEF_DPTwo 0x4000000000000000ULL
89 #define DEF_DPThree 0x4008000000000000ULL
90 #define DEF_DPFour 0x4010000000000000ULL
91 #define DEF_DPTwenty 0x4034000000000000ULL
93 ptr = (LONG *)&FFPOne; *ptr = DEF_FFPOne;
94 ptr = (LONG *)&FFPTwo; *ptr = DEF_FFPTwo;
95 ptr = (LONG *)&FFPMinusOne; *ptr = DEF_FFPMinusOne;
96 ptr = (LONG *)&FFPOnehalf; *ptr = DEF_FFPOnehalf;
97 ptr = (LONG *)&FFPNull; *ptr = DEF_FFPNull;
99 ptr = (LONG *)&SPOne; *ptr = DEF_SPOne;
100 ptr = (LONG *)&SPOnehalf; *ptr = DEF_SPOnehalf;
101 ptr = (LONG *)&SPTwo; *ptr = DEF_SPTwo;
103 /* if you deactivate #define float LONG something very funny happens here:
104 Printf("two: %x <-> %x \n",*ptr,SPTwo);
105 Printf("two: %x <-> %x \n",SPTwo,*ptr);
108 #define CHECK(func, args, cres) \
109 float_res = func args; \
110 if (*float_resptr != cres) \
111 Printf ("FAIL: " #func " " #args " in line %ld (got=0x%08lx expected=0x%08lx)\n", \
112 __LINE__, (unsigned long)*float_resptr, (unsigned long)cres); \
113 else \
114 Printf ("OK : " #func " " #args "\n");
117 When using doubles or QUADs it is important to pay attention to the Endianess of the processor,
118 otherwise you'll never see what you want to see.
121 #define CHECK_DOUBLE1A(func, arg1, cres) \
122 double_res = func (arg1); \
123 tested++; \
124 if (*double_resptr != cres) \
126 if (0 != AROS_BIG_ENDIAN) \
128 Printf ("FAIL: " #func " " #arg1 " in line %ld (got=0x%08lx%08lx expected=0x%08lx%08lx)\n", \
129 __LINE__, \
130 (unsigned long)(((QUAD)*double_resptr)>>32),(unsigned long)*(((LONG *)double_resptr)+1), \
131 (unsigned long)(((QUAD)cres)>>32),(unsigned long)cres); \
133 else \
135 Printf ("(little endian) FAIL: " #func " " #arg1 " in line %ld (got=0x%08lx%08lx expected=0x%08lx%08lx)\n", \
136 __LINE__, \
137 (unsigned long)*(((LONG *)double_resptr)+1),(unsigned long)*(((LONG *)double_resptr)), \
138 (unsigned long)(((QUAD)cres)>>32),(unsigned long)cres); \
141 else \
142 Printf ("OK : " #func " " #arg1 "\n");
144 #define CHECK_DOUBLE1AF(func, cres) \
145 tested++; \
146 if (*double_resptr != cres) \
148 if (0 != AROS_BIG_ENDIAN) \
150 Printf ("FAIL: " #func " in line %ld (got=0x%08lx%08lx expected=0x%08lx%08lx)\n", \
151 __LINE__, \
152 (unsigned long)(((QUAD)*double_resptr)>>32),(unsigned long)*(((LONG *)double_resptr)+1), \
153 (unsigned long)(((QUAD)cres)>>32),(unsigned long)cres); \
155 else \
157 Printf ("(little endian) FAIL: " #func " in line %ld (got=0x%08lx%08lx expected=0x%08lx%08lx)\n", \
158 __LINE__, \
159 (unsigned long)*(((LONG *)double_resptr)+1),(unsigned long)*(((LONG *)double_resptr)), \
160 (unsigned long)(((QUAD)cres)>>32),(unsigned long)cres); \
163 else { \
164 passed++; \
165 Printf ("OK : " #func "\n"); \
168 #define CHECK_DOUBLE1B(func, arg1, cres) \
169 QArg1 = arg1; \
170 double_res = func (*Darg1); \
171 tested++; \
172 if (*double_resptr != cres) \
174 if (0 != AROS_BIG_ENDIAN) \
176 Printf ("FAIL: " #func " " #arg1 " in line %ld (got=0x%08lx%08lx expected=0x%08lx%08lx)\n", \
177 __LINE__, \
178 (unsigned long)(((QUAD)*double_resptr)>>32),(unsigned long)*(((LONG *)double_resptr)+1), \
179 (unsigned long)(((QUAD)cres)>>32),(unsigned long)cres); \
181 else \
183 Printf ("(little endian) FAIL: " #func " " #arg1 " in line %ld (got=0x%08lx%08lx expected=0x%08lx%08lx)\n", \
184 __LINE__, \
185 (unsigned long)*(((LONG *)double_resptr)+1),(unsigned long)*(((LONG *)double_resptr)), \
186 (unsigned long)(((QUAD)cres)>>32),(unsigned long)cres); \
189 else { \
190 passed++; \
191 Printf ("OK : " #func " " #arg1 "\n"); \
194 #define CHECK_DOUBLE2A(func, arg1, arg2, cres) \
195 double_res = func (arg1, arg2); \
196 double_res2 = cres; \
197 tested++; \
198 if (double_res != double_res2) \
200 if (0 != AROS_BIG_ENDIAN) \
202 Printf ("FAIL: " #func " (" #arg1 "," #arg2 ") in line %ld (got=0x%08lx%08lx expected=0x%08lx%08lx)\n", \
203 __LINE__, \
204 (unsigned long)(((QUAD)*double_resptr )>>32),(unsigned long)*(((LONG *)double_resptr )+1), \
205 (unsigned long)(((QUAD)*double_resptr2)>>32),(unsigned long)*(((LONG *)double_resptr2)+1) ); \
207 else \
209 Printf ("(little endian) FAIL: " #func " (" #arg1 "," #arg2 ") in line %ld (got=0x%08lx%08lx expected=0x%08lx%08lx)\n", \
210 __LINE__, \
211 (unsigned long)*(((LONG *)double_resptr )+1),(unsigned long)*(((LONG *)double_resptr)), \
212 (unsigned long)*(((LONG *)double_resptr2)+1),(unsigned long)*(((LONG *)double_resptr2)) ); \
215 else { \
216 passed++; \
217 Printf ("OK : " #func " ( " #arg1 "," #arg2 " ) \n"); \
221 if (!(MathBase = OpenLibrary("mathffp.library", 0L)))
223 Printf ("Couldn't open mathffp.library\n");
224 return RETURN_FAIL;
227 Printf("Very basic mathffp functionality test...\n");
229 /* this should set the zero-bit*/
230 wanted = DEF_FFPNull; CHECK(SPAbs,(0),wanted);
232 wanted = DEF_FFPNull; CHECK(SPFlt,(0),wanted);
233 wanted = DEF_FFPOne; CHECK(SPFlt,(1),wanted);
234 wanted = DEF_FFPTwo; CHECK(SPFlt,(2),wanted);
235 wanted = DEF_FFPMinusOne; CHECK(SPFlt,(-1),wanted);
236 wanted = DEF_FFPTwo; CHECK(SPAdd,(FFPOne, FFPOne),wanted);
237 wanted = DEF_FFPOnehalf; CHECK(SPDiv,(FFPTwo, FFPOne),wanted);
238 wanted = DEF_FFPTwo; CHECK(SPMul,(FFPOne, FFPTwo),wanted);
240 CHECK(SPMul, (SPFlt(-1000), SPFlt(-10)), 0x9c40004e);
241 CHECK(SPDiv, (SPFlt(-10), SPFlt(-1000)), 0xc8000047);
242 CHECK(SPDiv, (SPFlt(0), SPFlt(1000)), 0);
244 /* Should also check condition codes but impossible without assembly */
245 CHECK(SPCmp, (SPFlt(10),SPFlt(15)), -1);
246 CHECK(SPCmp, (SPFlt(10),SPFlt(-15)), 1);
247 CHECK(SPCmp, (SPFlt(-10),SPFlt(-15)), 1);
248 CHECK(SPCmp, (SPFlt(-15),SPFlt(-10)), -1);
249 CHECK(SPCmp, (SPFlt(10),SPFlt(10)), 0);
250 CHECK(SPTst, (SPFlt(-1)), -1);
251 CHECK(SPTst, (SPFlt(0)), 0);
252 CHECK(SPTst, (SPFlt(1)), 1);
254 CloseLibrary(MathBase);
256 if (!(MathTransBase = OpenLibrary("mathtrans.library", 0L)))
258 Printf ("Couldn't open mathtrans.library\n");
259 return RETURN_FAIL;
262 Printf("Very basic mathtrans functionality test...\n");
264 CHECK (SPLog, (FFPTwo), 0xb1721840UL);
265 CHECK (SPLog10, (FFPTwo), 0x9a209b3fUL);
266 CHECK (SPSin, (FFPOne), 0xd76aa440UL);
267 CHECK (SPCos, (FFPOne), 0x8a514040UL);
268 CHECK (SPTan, (FFPOne), 0xc7592341UL);
269 CHECK (SPSinh, (FFPOne), 0x966cfe41UL);
270 CHECK (SPCosh, (FFPOne), 0xc583aa41UL);
271 CHECK (SPTanh, (FFPOne), 0xc2f7d640UL);
272 CHECK (SPExp, (FFPTwo), 0xec732543UL);
273 CHECK (SPAsin, (FFPOnehalf), 0x860a9240UL);
274 CHECK (SPAcos, (FFPOnehalf), 0x860a9241UL);
276 CloseLibrary(MathTransBase);
278 if (!(MathIeeeSingBasBase = OpenLibrary("mathieeesingbas.library", 0L)))
280 Printf ("Couldn't open mathieeesingbas.library\n");
281 return RETURN_FAIL;
285 if (!(MathIeeeSingTransBase = OpenLibrary("mathieeesingtrans.library", 0L)))
287 Printf ("Couldn't open mathieeesingtrans.library\n");
288 return RETURN_FAIL;
291 Printf("Very basic mathieeesingtrans functionality test...\n");
294 CHECK (IEEESPLog, (SPTwo), 0x3f317218UL);
295 CHECK (IEEESPLog10, (SPTwo), 0x3e9a209aUL);
296 CHECK (IEEESPSin, (SPOne), 0x3f576aa4UL);
297 CHECK (IEEESPCos, (SPOne), 0x3f0a5140UL);
298 CHECK (IEEESPTan, (SPOne), 0x3fc75923UL);
299 CHECK (IEEESPSinh, (SPTwo), 0x40681e7bUL);
300 CHECK (IEEESPCosh, (SPTwo), 0x4070c7d1UL);
301 CHECK (IEEESPTanh, (SPOne), 0x3f42f7d6UL);
302 CHECK (IEEESPExp, (SPTwo), 0x40ec7325UL);
303 CHECK (IEEESPAsin, (SPOnehalf), 0x3f060a92UL);
304 CHECK (IEEESPAcos, (SPOnehalf), 0x3f860a92UL);
306 CloseLibrary(MathIeeeSingTransBase);
308 if (!(MathIeeeDoubBasBase = OpenLibrary("mathieeedoubbas.library", 0L)))
310 Printf ("Couldn't open mathieeedoubbas.library\n");
311 return RETURN_FAIL;
316 CHECK_DOUBLE1A(IEEEDPFlt, ((LONG)1), DEF_DPOne);
317 CHECK_DOUBLE1A(IEEEDPFlt, ((LONG)2), DEF_DPTwo);
318 CHECK_DOUBLE1A(IEEEDPFlt, ((LONG)3), DEF_DPThree);
319 CHECK_DOUBLE1A(IEEEDPFlt, ((LONG)20), DEF_DPTwenty);
320 CHECK_DOUBLE1B(IEEEDPAbs, ((QUAD)DEF_DPMinusOne), (QUAD)DEF_DPOne);
321 CHECK_DOUBLE1B(IEEEDPNeg, ((QUAD)DEF_DPMinusOne), (QUAD)DEF_DPOne);
322 CHECK_DOUBLE2A(IEEEDPAdd, IEEEDPFlt(1), IEEEDPFlt(1), IEEEDPFlt(2));
323 CHECK_DOUBLE2A(IEEEDPAdd, IEEEDPFlt(123456), IEEEDPFlt(654321), IEEEDPFlt(777777));
324 CHECK_DOUBLE2A(IEEEDPSub, IEEEDPFlt(123456), IEEEDPFlt(654321), IEEEDPFlt(-530865));
325 CHECK_DOUBLE2A(IEEEDPMul, IEEEDPFlt(321), IEEEDPFlt(123456), IEEEDPFlt(39629376));
326 CHECK_DOUBLE2A(IEEEDPMul, IEEEDPFlt(2), IEEEDPFlt(2), IEEEDPFlt(4));
327 CHECK_DOUBLE2A(IEEEDPMul, IEEEDPFlt(20), IEEEDPFlt(20), IEEEDPFlt(400));
328 CHECK_DOUBLE2A(IEEEDPDiv, IEEEDPFlt(39629376),IEEEDPFlt(123456),IEEEDPFlt(321));
329 CHECK_DOUBLE2A(IEEEDPDiv, IEEEDPFlt(4), IEEEDPFlt(2), IEEEDPFlt(2));
330 CHECK_DOUBLE2A(IEEEDPDiv, IEEEDPFlt(400), IEEEDPFlt(20), IEEEDPFlt(20));
332 if (!(MathIeeeDoubTransBase = OpenLibrary("mathieeedoubtrans.library", 0L)))
334 Printf ("Couldn't open mathieeedoubtrans.library\n");
335 return RETURN_FAIL;
338 CHECK_DOUBLE1A(IEEEDPSqrt, ((double)IEEEDPFlt(4)), DEF_DPTwo);
339 CHECK_DOUBLE1A(IEEEDPSqrt, ((double)IEEEDPFlt(9)), DEF_DPThree);
340 CHECK_DOUBLE1A(IEEEDPCos, ((double)IEEEDPFlt(1)), 0x3fe14a280fb5068bULL);
341 CHECK_DOUBLE1A(IEEEDPSin, ((double)IEEEDPFlt(1)), 0x3feaed548f090ceeULL);
343 double_res = IEEEDPSincos(&double_res2, (double)IEEEDPFlt(1));
344 CHECK_DOUBLE1AF(IEEEDPSincos, 0x3feaed548f090ceeULL);
345 double_res = double_res2;
346 CHECK_DOUBLE1AF(IEEEDPSincos, 0x3fe14a280fb5068bULL);
348 wanted = IEEEDPTieee(IEEEDPFlt(2));
349 Printf("IEEEDPTieee(2) = %08lx\n", (LONG)wanted);
351 double_res = IEEEDPFieee(SPFlt(2));
352 CHECK_DOUBLE1AF(IEEEDPFieee, DEF_DPTwo);
354 CloseLibrary(MathIeeeDoubTransBase);
355 CloseLibrary(MathIeeeDoubBasBase);
357 Printf("Passed %ld of %ld tests\n", passed, tested);
358 return (tested == passed) ? RETURN_OK : RETURN_FAIL;