|
12 | 12 | #include <float.h> |
13 | 13 | #include <fenv.h> |
14 | 14 |
|
15 | | -typedef uint32_t Decimal32; |
16 | | -typedef uint64_t Decimal64; |
| 15 | +typedef BID_UINT32 Decimal32; |
| 16 | +typedef BID_UINT64 Decimal64; |
17 | 17 | #include "../LIBRARY/src/bid_conf.h" |
18 | 18 | #include "../LIBRARY/src/bid_functions.h" |
19 | 19 | typedef BID_UINT128 Decimal128; |
@@ -49,7 +49,7 @@ __attribute__ ((noinline)) void generate_vector_32(Decimal32* buffer, size_t buf |
49 | 49 | { |
50 | 50 | for (size_t i = 0; i < buffer_len; ++i) |
51 | 51 | { |
52 | | - buffer[i] = bid32_from_uint32(random_uint32(), BID_ROUNDING_DOWN, &flag); |
| 52 | + buffer[i] = bid32_from_uint32(random_uint32(), BID_ROUNDING_TO_NEAREST, &flag); |
53 | 53 | } |
54 | 54 | } |
55 | 55 |
|
@@ -86,7 +86,7 @@ __attribute__ ((noinline)) void generate_vector_64(Decimal64* buffer, size_t buf |
86 | 86 | { |
87 | 87 | for (size_t i = 0; i < buffer_len; ++i) |
88 | 88 | { |
89 | | - buffer[i] = bid64_from_uint64(random_uint64(), BID_ROUNDING_DOWN, &flag); |
| 89 | + buffer[i] = bid64_from_uint64(random_uint64(), BID_ROUNDING_TO_NEAREST, &flag); |
90 | 90 | } |
91 | 91 | } |
92 | 92 |
|
@@ -119,13 +119,51 @@ __attribute__ ((noinline)) void test_comparisons_64(Decimal64* data, const char* |
119 | 119 | printf("Comparisons <%-10s >: %-10" PRIu64 " us (s=%zu)\n", label, elapsed_time_us, s); |
120 | 120 | } |
121 | 121 |
|
| 122 | +Decimal128 random_decimal128(void) |
| 123 | +{ |
| 124 | + char str[64]; // Plenty of room for: -d.dddddddddddddddddddddddddddddddddE±eeee |
| 125 | + |
| 126 | + // 1. Random sign (50/50) |
| 127 | + char sign = (random_uint64() & 1) ? '-' : '+'; |
| 128 | + |
| 129 | + // 2. Random 34-digit significand |
| 130 | + char digits[35]; |
| 131 | + for (int i = 0; i < 34; i++) |
| 132 | + { |
| 133 | + digits[i] = '0' + (random_uint64() % 10); |
| 134 | + } |
| 135 | + |
| 136 | + // Ensure first digit is non-zero (avoid leading zeros affecting value) |
| 137 | + if (digits[0] == '0') |
| 138 | + { |
| 139 | + digits[0] = '1' + (random_uint64() % 9); |
| 140 | + } |
| 141 | + digits[34] = '\0'; |
| 142 | + |
| 143 | + // 3. Random exponent: -6143 to +6144 |
| 144 | + int exp_range = 6144 - (-6143) + 1; // 12288 possible values |
| 145 | + int exponent = (int)(random_uint64() % exp_range) - 6143; |
| 146 | + |
| 147 | + // 4. Build string: "±D.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDE±EEEE" |
| 148 | + snprintf(str, sizeof(str), "%c%c.%sE%+d", |
| 149 | + sign, |
| 150 | + digits[0], // integer part (1 digit) |
| 151 | + &digits[1], // fractional part (33 digits) |
| 152 | + exponent); |
| 153 | + |
| 154 | + // 5. Parse to decimal128 |
| 155 | + _IDEC_flags flags = 0; |
| 156 | + Decimal128 result = bid128_from_string(str, &flags); |
| 157 | + |
| 158 | + return result; |
| 159 | +} |
122 | 160 |
|
123 | 161 | __attribute__ ((__noinline__)) void generate_vector_128(Decimal128* buffer, size_t buffer_len) |
124 | 162 | { |
125 | 163 | size_t i = 0; |
126 | 164 | while (i < buffer_len) |
127 | 165 | { |
128 | | - buffer[i] = bid128_from_uint64(random_uint64()); |
| 166 | + buffer[i] = random_decimal128(); |
129 | 167 | ++i; |
130 | 168 | } |
131 | 169 | } |
@@ -164,21 +202,21 @@ typedef Decimal32 (*operation_32)(Decimal32, Decimal32); |
164 | 202 |
|
165 | 203 | __attribute__ ((noinline)) Decimal32 add_32(Decimal32 a, Decimal32 b) |
166 | 204 | { |
167 | | - return bid32_add(a, b, BID_ROUNDING_DOWN, &flag); |
| 205 | + return bid32_add(a, b, BID_ROUNDING_TO_NEAREST, &flag); |
168 | 206 | } |
169 | 207 | __attribute__ ((noinline)) Decimal32 sub_32(Decimal32 a, Decimal32 b) |
170 | 208 | { |
171 | | - return bid32_sub(a, b, BID_ROUNDING_DOWN, &flag); |
| 209 | + return bid32_sub(a, b, BID_ROUNDING_TO_NEAREST, &flag); |
172 | 210 | } |
173 | 211 |
|
174 | 212 | __attribute__ ((noinline)) Decimal32 mul_32(Decimal32 a, Decimal32 b) |
175 | 213 | { |
176 | | - return bid32_mul(a, b, BID_ROUNDING_DOWN, &flag); |
| 214 | + return bid32_mul(a, b, BID_ROUNDING_TO_NEAREST, &flag); |
177 | 215 | } |
178 | 216 |
|
179 | 217 | __attribute__ ((noinline)) Decimal32 div_32(Decimal32 a, Decimal32 b) |
180 | 218 | { |
181 | | - return bid32_div(a, b, BID_ROUNDING_DOWN, &flag); |
| 219 | + return bid32_div(a, b, BID_ROUNDING_TO_NEAREST, &flag); |
182 | 220 | } |
183 | 221 |
|
184 | 222 | __attribute__ ((noinline)) void test_two_element_operation_32(Decimal32* data, operation_32 op, const char* label, const char* op_label) |
@@ -209,22 +247,22 @@ typedef Decimal64 (*operation_64)(Decimal64, Decimal64); |
209 | 247 |
|
210 | 248 | __attribute__ ((noinline)) Decimal64 add_64(Decimal64 a, Decimal64 b) |
211 | 249 | { |
212 | | - return bid64_add(a, b, BID_ROUNDING_DOWN, &flag); |
| 250 | + return bid64_add(a, b, BID_ROUNDING_TO_NEAREST, &flag); |
213 | 251 | } |
214 | 252 |
|
215 | 253 | __attribute__ ((noinline)) Decimal64 sub_64(Decimal64 a, Decimal64 b) |
216 | 254 | { |
217 | | - return bid64_sub(a, b, BID_ROUNDING_DOWN, &flag); |
| 255 | + return bid64_sub(a, b, BID_ROUNDING_TO_NEAREST, &flag); |
218 | 256 | } |
219 | 257 |
|
220 | 258 | __attribute__ ((noinline)) Decimal64 mul_64(Decimal64 a, Decimal64 b) |
221 | 259 | { |
222 | | - return bid64_mul(a, b, BID_ROUNDING_DOWN, &flag); |
| 260 | + return bid64_mul(a, b, BID_ROUNDING_TO_NEAREST, &flag); |
223 | 261 | } |
224 | 262 |
|
225 | 263 | __attribute__ ((noinline)) Decimal64 div_64(Decimal64 a, Decimal64 b) |
226 | 264 | { |
227 | | - return bid64_div(a, b, BID_ROUNDING_DOWN, &flag); |
| 265 | + return bid64_div(a, b, BID_ROUNDING_TO_NEAREST, &flag); |
228 | 266 | } |
229 | 267 |
|
230 | 268 | __attribute__ ((noinline)) void test_two_element_operation_64(Decimal64* data, operation_64 op, const char* label, const char* op_label) |
@@ -256,22 +294,22 @@ typedef Decimal128 (*operation_128)(Decimal128, Decimal128); |
256 | 294 |
|
257 | 295 | __attribute__ ((__noinline__)) Decimal128 add_128(Decimal128 a, Decimal128 b) |
258 | 296 | { |
259 | | - return bid128_add(a, b, BID_ROUNDING_DOWN, &flag); |
| 297 | + return bid128_add(a, b, BID_ROUNDING_TO_NEAREST, &flag); |
260 | 298 | } |
261 | 299 |
|
262 | 300 | __attribute__ ((__noinline__)) Decimal128 sub_128(Decimal128 a, Decimal128 b) |
263 | 301 | { |
264 | | - return bid128_sub(a, b, BID_ROUNDING_DOWN, &flag); |
| 302 | + return bid128_sub(a, b, BID_ROUNDING_TO_NEAREST, &flag); |
265 | 303 | } |
266 | 304 |
|
267 | 305 | __attribute__ ((__noinline__)) Decimal128 mul_128(Decimal128 a, Decimal128 b) |
268 | 306 | { |
269 | | - return bid128_mul(a, b, BID_ROUNDING_DOWN, &flag); |
| 307 | + return bid128_mul(a, b, BID_ROUNDING_TO_NEAREST, &flag); |
270 | 308 | } |
271 | 309 |
|
272 | 310 | __attribute__ ((__noinline__)) Decimal128 div_128(Decimal128 a, Decimal128 b) |
273 | 311 | { |
274 | | - return bid128_div(a, b, BID_ROUNDING_DOWN, &flag); |
| 312 | + return bid128_div(a, b, BID_ROUNDING_TO_NEAREST, &flag); |
275 | 313 | } |
276 | 314 |
|
277 | 315 | __attribute__ ((__noinline__)) void test_two_element_operation_128(Decimal128* data, operation_128 op, const char* label, const char* op_label) |
|
0 commit comments