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
|
#include <stdio.h>
#include <math.h>
extern void intoffloat(int * r, double * x);
extern void intuoffloat(unsigned int * r, double * x);
extern void floatofint(double * r, int * x);
extern void floatofintu(double * r, unsigned int * x);
/* Linear congruential PRNG */
static unsigned int random_seed = 0;
unsigned int random_uint(void)
{
random_seed = random_seed * 69069 + 25173;
return random_seed;
}
double random_double(void)
{
/* In range 0 .. 2^32+1 */
unsigned int h = random_uint();
unsigned int l = random_uint();
return (double) h + ldexp((double) l, -32);
}
/* Individual test runs */
void test_intoffloat(double x)
{
int r;
intoffloat(&r, &x);
if (r != (int) x)
printf("intoffloat(%g): expected %d, got %d\n", x, r, (int) x);
}
void test_intuoffloat(double x)
{
unsigned int r;
intuoffloat(&r, &x);
if (r != (unsigned int) x)
printf("intuoffloat(%g): expected %d, got %d\n", x, r, (unsigned int) x);
}
void test_floatofint(int x)
{
double r;
floatofint(&r, &x);
if (r != (double) x)
printf("floatofint(%d): expected %g, got %g\n", x, r, (double) x);
}
void test_floatofintu(unsigned int x)
{
double r;
floatofintu(&r, &x);
if (r != (double) x)
printf("floatofint(%u): expected %g, got %g\n", x, r, (double) x);
}
/* Limit cases */
double cases_intoffloat[] = {
0.0, 0.1, 0.5, 0.9, 1.0, 1.1, 1.6,
-0.1, -0.5, -0.9, -1.0, -1.1, -1.6,
2147483647.0, 2147483647.6, 2147483648.0, 2147483647.5,
2147483648.0, 2147483648.5, 2147483649.0, 10000000000.0,
-2147483647.0, -2147483647.6, -2147483648.0, -2147483647.5,
-2147483648.0, -2147483648.5, -2147483649.0, -10000000000.0
};
double cases_intuoffloat[] = {
0.0, 0.1, 0.5, 0.9, 1.0, 1.1, 1.6,
-0.1, -0.5, -0.9, -1.0, -1.1, -1.6,
2147483647.0, 2147483647.6, 2147483648.0, 2147483647.5,
2147483648.0, 2147483648.5, 2147483649.0,
4294967295.0, 4294967295.6, 4294967296.0, 4294967296.5,
10000000000.0
};
int cases_floatofint[] = {
0, 1, 2, -1, -2, 2147483647, -2147483648
};
unsigned int cases_floatofintu[] = {
0U, 1U, 2U, 2147483647U, 2147483648U, 4294967295U
};
#define TEST(testfun, cases, tyarg, gen) \
for (i = 0; i < sizeof(cases) / sizeof(tyarg); i++) \
testfun(cases[i]); \
for (i = 0; i < numtests; i++) \
testfun(gen);
int main(int argc, char ** argv)
{
int i;
int numtests = 1000000;
TEST(test_intoffloat, cases_intoffloat, double,
(random_double() - 2147483648.0));
TEST(test_intuoffloat, cases_intuoffloat, double,
random_double());
TEST(test_floatofint, cases_floatofint, int,
(int) random_uint());
TEST(test_floatofintu, cases_floatofintu, unsigned int,
random_uint());
return 0;
}
|