1 // posit256.c: example test of the posit API for C programs using 256-bit posits
2 //
3 // Copyright (C) 2017-2021 Stillwater Supercomputing, Inc.
4 //
5 // This file is part of the universal numbers project, which is released under an MIT Open Source license.
6
7 #define POSIT_NO_GENERICS // MSVC doesn't support _Generic so we'll leave it out from these tests
8 #include <universal/number/posit/posit_c_api.h>
9
main(int argc,char * argv[])10 int main(int argc, char* argv[])
11 {
12 const int maxNr = 96;
13 posit256_t pa, pb, pc;
14 char str[posit256_str_SIZE];
15 bool failures = false;
16 bool bReportIndividualTestCases = false;
17
18 // special case values
19 pa = NAR256;
20 pb = ZERO256;
21 pc = posit256_add(pa, pb);
22 posit256_str(str, pc);
23 printf("posit value = %s\n", str);
24
25 pa = NAR256;
26 pb = ZERO256;
27 pc = posit256_sub(pa, pb);
28 posit256_str(str, pc);
29 printf("posit value = %s\n", str);
30
31 pa = NAR256;
32 pb = ZERO256;
33 pc = posit256_mul(pa, pb);
34 posit256_str(str, pc);
35 printf("posit value = %s\n", str);
36
37 pa = NAR256;
38 pb = ZERO256;
39 pc = posit256_div(pa, pb);
40 posit256_str(str, pc);
41 printf("posit value = %s\n", str);
42
43 bool noReference = true;
44 printf("Sizeof (long double) is %zu, which isn't sufficiently precise to validate posit<<256,4>>\n", sizeof(long double));
45
46 // partial state space
47 int fails = 0;
48 for (int a = 0; a < maxNr; ++a) {
49 pa = posit256_reinterpret( (uint64_t[]){ a, 0, 0, 0 } );
50 for (int b = 0; b < maxNr; ++b) {
51 pb = posit256_reinterpret( (uint64_t[]){ b, 0, 0, 0 } );
52 pc = posit256_add(pa, pb);
53
54 long double da, db, dref;
55 da = posit256_told(pa);
56 db = posit256_told(pb);
57 dref = da + db;
58
59 posit256_t pref = posit256_fromld(dref);
60
61 if (posit256_cmp(pref, pc)) {
62 char sa[posit256_str_SIZE], sb[posit256_str_SIZE], sc[posit256_str_SIZE], sref[posit256_str_SIZE];
63 posit256_str(sa, pa);
64 posit256_str(sb, pb);
65 posit256_str(sc, pc);
66 posit256_str(sref, pref);
67
68 if (bReportIndividualTestCases) printf("FAIL: %s + %s produced %s instead of %s\n", sa, sb, sc, sref);
69 ++fails;
70 }
71 }
72 }
73 if (fails) {
74 if (noReference) {
75 printf("addition uncertain\n");
76 }
77 else {
78 printf("addition FAIL\n");
79 failures = true;
80 }
81 }
82 else {
83 printf("addition PASS\n");
84 }
85
86 // partial state space
87 fails = 0;
88 for (int a = 0; a < maxNr; ++a) {
89 pa = posit256_reinterpret( (uint64_t[]){ a, 0, 0, 0 } );
90 for (int b = 0; b < maxNr; ++b) {
91 pb = posit256_reinterpret( (uint64_t[]){ b, 0, 0, 0 } );
92 pc = posit256_sub(pa, pb);
93
94 long double da, db, dref;
95 da = posit256_told(pa);
96 db = posit256_told(pb);
97 dref = da - db;
98
99 posit256_t pref = posit256_fromld(dref);
100 if (posit256_cmp(pref, pc)) {
101 char sa[posit256_str_SIZE], sb[posit256_str_SIZE], sc[posit256_str_SIZE], sref[posit256_str_SIZE];
102 posit256_str(sa, pa);
103 posit256_str(sb, pb);
104 posit256_str(sc, pc);
105 posit256_str(sref, pref);
106
107 if (bReportIndividualTestCases) printf("FAIL: %s - %s produced %s instead of %s\n", sa, sb, sc, sref);
108 ++fails;
109 }
110 }
111 }
112 if (fails) {
113 if (noReference) {
114 printf("subtraction uncertain\n");
115 }
116 else {
117 printf("subtraction FAIL\n");
118 failures = true;
119 }
120 }
121 else {
122 printf("subtraction PASS\n");
123 }
124
125 // partial state space
126 fails = 0;
127 for (int a = 0; a < maxNr; ++a) {
128 pa = posit256_reinterpret( (uint64_t[]){ a, 0, 0, 0 } );
129 for (int b = 0; b < maxNr; ++b) {
130 pb = posit256_reinterpret( (uint64_t[]){ b, 0, 0, 0 } );
131 pc = posit256_mul(pa, pb);
132
133 long double da, db, dref;
134 da = posit256_told(pa);
135 db = posit256_told(pb);
136 dref = da * db;
137
138 posit256_t pref = posit256_fromld(dref);
139
140 if (posit256_cmp(pref, pc)) {
141 char sa[posit256_str_SIZE], sb[posit256_str_SIZE], sc[posit256_str_SIZE], sref[posit256_str_SIZE];
142 posit256_str(sa, pa);
143 posit256_str(sb, pb);
144 posit256_str(sc, pc);
145 posit256_str(sref, pref);
146
147 if (bReportIndividualTestCases) printf("FAIL: %s * %s produced %s instead of %s\n", sa, sb, sc, sref);
148 ++fails;
149 }
150 }
151 }
152 if (fails) {
153 if (noReference) {
154 printf("multiplication uncertain\n");
155 }
156 else {
157 printf("multiplication FAIL\n");
158 failures = true;
159 }
160 }
161 else {
162 printf("multiplication PASS\n");
163 }
164
165 // partial state space
166 fails = 0;
167 for (int a = 0; a < maxNr; ++a) {
168 pa = posit256_reinterpret( (uint64_t[]){ a, 0, 0, 0 } );
169 for (int b = 0; b < maxNr; ++b) {
170 pb = posit256_reinterpret( (uint64_t[]){ b, 0, 0, 0 } );
171 pc = posit256_div(pa, pb);
172
173 long double da, db, dref;
174 da = posit256_told(pa);
175 db = posit256_told(pb);
176 dref = da / db;
177
178 posit256_t pref = posit256_fromld(dref);
179
180 if (posit256_cmp(pref, pc)) {
181 char sa[posit256_str_SIZE], sb[posit256_str_SIZE], sc[posit256_str_SIZE], sref[posit256_str_SIZE];
182 posit256_str(sa, pa);
183 posit256_str(sb, pb);
184 posit256_str(sc, pc);
185 posit256_str(sref, pref);
186
187 if (bReportIndividualTestCases) printf("FAIL: %s / %s produced %s instead of %s\n", sa, sb, sc, sref);
188 ++fails;
189 }
190 }
191 }
192 if (fails) {
193 if (noReference) {
194 printf("division uncertain\n");
195 }
196 else {
197 printf("division FAIL\n");
198 failures = true;
199 }
200 }
201 else {
202 printf("division PASS\n");
203 }
204
205 return failures > 0 ? EXIT_FAILURE : EXIT_SUCCESS;
206 }
207