Lev Walkin | 4eceeba | 2007-07-23 06:48:26 +0000 | [diff] [blame] | 1 | #include <stdio.h> |
| 2 | #include <assert.h> |
| 3 | #include <math.h> |
Lev Walkin | 8ca13c8 | 2016-01-24 22:40:00 -0800 | [diff] [blame] | 4 | #include <float.h> |
Lev Walkin | 4eceeba | 2007-07-23 06:48:26 +0000 | [diff] [blame] | 5 | |
Lev Walkin | 681f059 | 2016-03-14 04:21:26 -0700 | [diff] [blame] | 6 | /* C11 specifies DBL_TRUE_MIN, might not be immediately available. */ |
| 7 | #ifndef DBL_TRUE_MIN |
| 8 | #define DBL_TRUE_MIN 4.9406564584124654E-324 |
| 9 | #endif |
| 10 | |
Lev Walkin | 4eceeba | 2007-07-23 06:48:26 +0000 | [diff] [blame] | 11 | #include <REAL.h> |
Lev Walkin | 41ba1f2 | 2004-09-14 12:46:35 +0000 | [diff] [blame] | 12 | |
Lev Walkin | ed46543 | 2004-09-27 20:52:36 +0000 | [diff] [blame] | 13 | static char reconstructed[2][512]; |
| 14 | static int reconstr_lens[2]; |
| 15 | |
| 16 | static int |
| 17 | callback(const void *buffer, size_t size, void *app_key) { |
| 18 | char *buf = reconstructed[app_key ? 1 : 0]; |
| 19 | int *len = &reconstr_lens[app_key ? 1 : 0]; |
| 20 | |
| 21 | if(*len + size >= sizeof(reconstructed[0])) |
| 22 | return -1; |
| 23 | |
| 24 | memcpy(buf + *len, buffer, size); |
| 25 | *len += size; |
| 26 | |
| 27 | return 0; |
| 28 | } |
| 29 | |
Lev Walkin | 833d275 | 2012-01-07 15:29:25 -0800 | [diff] [blame] | 30 | static char * |
Lev Walkin | 9736348 | 2016-01-24 19:23:02 -0800 | [diff] [blame] | 31 | d2s(double d, int canonical) { |
Lev Walkin | 833d275 | 2012-01-07 15:29:25 -0800 | [diff] [blame] | 32 | ssize_t s; |
| 33 | |
| 34 | reconstr_lens[canonical] = 0; |
| 35 | s = REAL__dump(d, canonical, callback, (void *)(ptrdiff_t)canonical); |
Lev Walkin | 9736348 | 2016-01-24 19:23:02 -0800 | [diff] [blame] | 36 | assert(s > 0 && (size_t)s < sizeof(reconstructed[canonical])); |
Lev Walkin | 833d275 | 2012-01-07 15:29:25 -0800 | [diff] [blame] | 37 | assert(s == reconstr_lens[canonical]); |
| 38 | reconstructed[canonical][s] = '\0'; // ASCIIZ |
| 39 | return reconstructed[canonical]; |
| 40 | } |
| 41 | |
| 42 | /* |
| 43 | * Verify that a string representation of a given floating point value |
| 44 | * is as given in the (sample) and (canonical_sample) arguments. |
| 45 | */ |
Lev Walkin | 41ba1f2 | 2004-09-14 12:46:35 +0000 | [diff] [blame] | 46 | static void |
Lev Walkin | 5fda7d5 | 2012-01-09 03:20:19 -0800 | [diff] [blame] | 47 | check_str_representation(double d, const char *sample, const char *canonical_sample, int lineno) { |
Lev Walkin | 833d275 | 2012-01-07 15:29:25 -0800 | [diff] [blame] | 48 | char *s0, *s1; |
Lev Walkin | ed46543 | 2004-09-27 20:52:36 +0000 | [diff] [blame] | 49 | |
Lev Walkin | 9736348 | 2016-01-24 19:23:02 -0800 | [diff] [blame] | 50 | s0 = d2s(d, 0); |
| 51 | s1 = d2s(d, 1); |
Lev Walkin | ed46543 | 2004-09-27 20:52:36 +0000 | [diff] [blame] | 52 | |
| 53 | if(sample) { |
Lev Walkin | 8ca13c8 | 2016-01-24 22:40:00 -0800 | [diff] [blame] | 54 | printf("%03d: Checking %g->[\"%s\"] against [\"%s\"]%s\n", |
Lev Walkin | 5fda7d5 | 2012-01-09 03:20:19 -0800 | [diff] [blame] | 55 | lineno, d, s0, sample, |
Lev Walkin | f0b808d | 2005-04-25 21:08:25 +0000 | [diff] [blame] | 56 | canonical_sample ? " (canonical follows...)" : "" |
| 57 | ); |
Lev Walkin | 833d275 | 2012-01-07 15:29:25 -0800 | [diff] [blame] | 58 | assert(!strcmp(s0, sample)); |
Lev Walkin | ed46543 | 2004-09-27 20:52:36 +0000 | [diff] [blame] | 59 | } |
| 60 | if(canonical_sample) { |
Lev Walkin | 8ca13c8 | 2016-01-24 22:40:00 -0800 | [diff] [blame] | 61 | printf("%03d: Checking %g->[\"%s\"] against [\"%s\"] (canonical)\n", |
Lev Walkin | 5fda7d5 | 2012-01-09 03:20:19 -0800 | [diff] [blame] | 62 | lineno, d, s1, canonical_sample); |
Lev Walkin | 833d275 | 2012-01-07 15:29:25 -0800 | [diff] [blame] | 63 | assert(!strcmp(s1, canonical_sample)); |
Lev Walkin | ed46543 | 2004-09-27 20:52:36 +0000 | [diff] [blame] | 64 | } |
| 65 | } |
| 66 | |
Lev Walkin | 5fe72e9 | 2012-01-07 17:00:29 -0800 | [diff] [blame] | 67 | #define check(rn, d, str1, str2) \ |
| 68 | check_impl(rn, d, str1, str2, __LINE__) |
| 69 | |
Lev Walkin | ed46543 | 2004-09-27 20:52:36 +0000 | [diff] [blame] | 70 | static void |
Lev Walkin | 5fda7d5 | 2012-01-09 03:20:19 -0800 | [diff] [blame] | 71 | check_impl(REAL_t *rn, double orig_dbl, const char *sample, const char *canonical_sample, int lineno) { |
Lev Walkin | 41ba1f2 | 2004-09-14 12:46:35 +0000 | [diff] [blame] | 72 | double val; |
| 73 | uint8_t *p, *end; |
| 74 | int ret; |
| 75 | |
Lev Walkin | 5fda7d5 | 2012-01-09 03:20:19 -0800 | [diff] [blame] | 76 | printf("Line %d: double value %.12f [", lineno, orig_dbl); |
Lev Walkin | 41ba1f2 | 2004-09-14 12:46:35 +0000 | [diff] [blame] | 77 | for(p = (uint8_t *)&orig_dbl, end = p + sizeof(double); p < end ; p++) |
| 78 | printf("%02x", *p); |
| 79 | printf("] (ilogb %d)\n", ilogb(orig_dbl)); |
| 80 | |
| 81 | val = frexp(orig_dbl, &ret); |
| 82 | printf("frexp(%f, %d): [", val, ret); |
| 83 | for(p = (uint8_t *)&val, end = p + sizeof(double); p < end ; p++) |
| 84 | printf("%02x", *p); |
| 85 | printf("]\n"); |
| 86 | |
Lev Walkin | 5e03376 | 2004-09-29 13:26:15 +0000 | [diff] [blame] | 87 | ret = asn_double2REAL(rn, orig_dbl); |
Lev Walkin | 41ba1f2 | 2004-09-14 12:46:35 +0000 | [diff] [blame] | 88 | assert(ret == 0); |
| 89 | |
| 90 | printf("converted into ["); |
| 91 | for(p = rn->buf, end = p + rn->size; p < end; p++) |
| 92 | printf("%02x", *p); |
Lev Walkin | 2a789d9 | 2004-09-27 21:36:59 +0000 | [diff] [blame] | 93 | printf("]: %d\n", rn->size); |
Lev Walkin | 41ba1f2 | 2004-09-14 12:46:35 +0000 | [diff] [blame] | 94 | |
Lev Walkin | 5e03376 | 2004-09-29 13:26:15 +0000 | [diff] [blame] | 95 | ret = asn_REAL2double(rn, &val); |
Lev Walkin | 41ba1f2 | 2004-09-14 12:46:35 +0000 | [diff] [blame] | 96 | assert(ret == 0); |
| 97 | |
| 98 | printf("and back to double: ["); |
| 99 | for(p = (uint8_t *)&val, end = p + sizeof(double); p < end ; p++) |
| 100 | printf("%02x", *p); |
| 101 | printf("] (ilogb %d)\n", ilogb(val)); |
| 102 | |
Lev Walkin | 1aea698 | 2004-10-26 09:35:25 +0000 | [diff] [blame] | 103 | printf("%.12f vs %.12f\n", val, orig_dbl); |
| 104 | assert((isnan(orig_dbl) && isnan(val)) || val == orig_dbl); |
Lev Walkin | 41ba1f2 | 2004-09-14 12:46:35 +0000 | [diff] [blame] | 105 | printf("OK\n"); |
Lev Walkin | ed46543 | 2004-09-27 20:52:36 +0000 | [diff] [blame] | 106 | |
Lev Walkin | 5fda7d5 | 2012-01-09 03:20:19 -0800 | [diff] [blame] | 107 | check_str_representation(val, sample, canonical_sample, lineno); |
Lev Walkin | 41ba1f2 | 2004-09-14 12:46:35 +0000 | [diff] [blame] | 108 | } |
Lev Walkin | 5f56091 | 2004-10-21 13:37:57 +0000 | [diff] [blame] | 109 | static void |
| 110 | check_xer(int fuzzy, double orig_value) { |
| 111 | asn_enc_rval_t er; |
| 112 | asn_dec_rval_t rc; |
| 113 | REAL_t st; |
| 114 | REAL_t *newst0 = 0; |
| 115 | REAL_t *newst1 = 0; |
Lev Walkin | b191938 | 2006-07-27 11:46:25 +0000 | [diff] [blame] | 116 | REAL_t **newst0p = &newst0; |
| 117 | REAL_t **newst1p = &newst1; |
Lev Walkin | 5f56091 | 2004-10-21 13:37:57 +0000 | [diff] [blame] | 118 | double value0, value1; |
| 119 | int ret; |
| 120 | |
| 121 | memset(&st, 0, sizeof(st)); |
| 122 | ret = asn_double2REAL(&st, orig_value); |
| 123 | assert(ret == 0); |
| 124 | |
| 125 | reconstr_lens[0] = 0; |
| 126 | reconstr_lens[1] = 0; |
| 127 | er = xer_encode(&asn_DEF_REAL, &st, |
| 128 | XER_F_BASIC, callback, 0); |
| 129 | assert(er.encoded == reconstr_lens[0]); |
| 130 | er = xer_encode(&asn_DEF_REAL, &st, |
| 131 | XER_F_CANONICAL, callback, (void *)1); |
| 132 | assert(er.encoded == reconstr_lens[1]); |
| 133 | reconstructed[0][reconstr_lens[0]] = 0; |
| 134 | reconstructed[1][reconstr_lens[1]] = 0; |
| 135 | |
| 136 | printf("%f vs (%d)[%s] & (%d)%s", |
| 137 | orig_value, |
| 138 | reconstr_lens[1], reconstructed[1], |
| 139 | reconstr_lens[0], reconstructed[0] |
| 140 | ); |
| 141 | |
Lev Walkin | b191938 | 2006-07-27 11:46:25 +0000 | [diff] [blame] | 142 | rc = xer_decode(0, &asn_DEF_REAL, (void **)newst0p, |
Lev Walkin | 5f56091 | 2004-10-21 13:37:57 +0000 | [diff] [blame] | 143 | reconstructed[0], reconstr_lens[0]); |
| 144 | assert(rc.code == RC_OK); |
Lev Walkin | 9736348 | 2016-01-24 19:23:02 -0800 | [diff] [blame] | 145 | assert(reconstr_lens[0] > 0 && rc.consumed < (size_t)reconstr_lens[0]); |
Lev Walkin | 5f56091 | 2004-10-21 13:37:57 +0000 | [diff] [blame] | 146 | |
Lev Walkin | b191938 | 2006-07-27 11:46:25 +0000 | [diff] [blame] | 147 | rc = xer_decode(0, &asn_DEF_REAL, (void **)newst1p, |
Lev Walkin | 5f56091 | 2004-10-21 13:37:57 +0000 | [diff] [blame] | 148 | reconstructed[1], reconstr_lens[1]); |
| 149 | assert(rc.code == RC_OK); |
Lev Walkin | 9736348 | 2016-01-24 19:23:02 -0800 | [diff] [blame] | 150 | assert(rc.consumed == (size_t)reconstr_lens[1]); |
Lev Walkin | 5f56091 | 2004-10-21 13:37:57 +0000 | [diff] [blame] | 151 | |
| 152 | ret = asn_REAL2double(newst0, &value0); |
| 153 | assert(ret == 0); |
| 154 | ret = asn_REAL2double(newst1, &value1); |
| 155 | assert(ret == 0); |
| 156 | |
Lev Walkin | 1aea698 | 2004-10-26 09:35:25 +0000 | [diff] [blame] | 157 | assert((isnan(value0) && isnan(orig_value)) |
| 158 | || value0 == orig_value |
Lev Walkin | 5f56091 | 2004-10-21 13:37:57 +0000 | [diff] [blame] | 159 | || fuzzy); |
Lev Walkin | 1aea698 | 2004-10-26 09:35:25 +0000 | [diff] [blame] | 160 | assert((isnan(value1) && isnan(orig_value)) |
| 161 | || value1 == orig_value); |
Lev Walkin | 5f56091 | 2004-10-21 13:37:57 +0000 | [diff] [blame] | 162 | |
| 163 | assert(newst0->size == st.size || fuzzy); |
| 164 | assert(newst1->size == st.size); |
| 165 | assert(fuzzy || memcmp(newst0->buf, st.buf, st.size) == 0); |
| 166 | assert(memcmp(newst1->buf, st.buf, st.size) == 0); |
| 167 | } |
| 168 | |
Lev Walkin | 5fe72e9 | 2012-01-07 17:00:29 -0800 | [diff] [blame] | 169 | static void |
Lev Walkin | 5fda7d5 | 2012-01-09 03:20:19 -0800 | [diff] [blame] | 170 | check_ber_buffer_twoway(double d, const char *sample, const char *canonical_sample, uint8_t *inbuf, size_t insize, uint8_t *outbuf, size_t outsize, int lineno) { |
Lev Walkin | 5fe72e9 | 2012-01-07 17:00:29 -0800 | [diff] [blame] | 171 | REAL_t rn; |
| 172 | double val; |
| 173 | int ret; |
| 174 | |
| 175 | /* |
| 176 | * Decode our expected buffer and check that it matches the given (d). |
| 177 | */ |
| 178 | rn.buf = inbuf; |
| 179 | rn.size = insize; |
| 180 | asn_REAL2double(&rn, &val); |
| 181 | if(isnan(val)) assert(isnan(d)); |
| 182 | if(isnan(d)) assert(isnan(val)); |
| 183 | if(!isnan(val) && !isnan(d)) { |
Lev Walkin | 5fda7d5 | 2012-01-09 03:20:19 -0800 | [diff] [blame] | 184 | assert(copysign(1.0, d) == copysign(1.0, val)); |
| 185 | assert(d == val); |
| 186 | } |
Lev Walkin | 5fe72e9 | 2012-01-07 17:00:29 -0800 | [diff] [blame] | 187 | |
| 188 | /* |
| 189 | * Encode value and check that it matches our expected buffer. |
| 190 | */ |
| 191 | memset(&rn, 0, sizeof(rn)); |
| 192 | ret = asn_double2REAL(&rn, d); |
| 193 | assert(ret == 0); |
Lev Walkin | 9736348 | 2016-01-24 19:23:02 -0800 | [diff] [blame] | 194 | if((size_t)rn.size != outsize) { |
Lev Walkin | 5fe72e9 | 2012-01-07 17:00:29 -0800 | [diff] [blame] | 195 | printf("Encoded %f into %d expected %ld\n", |
| 196 | d, (int)rn.size, outsize); |
Lev Walkin | 9736348 | 2016-01-24 19:23:02 -0800 | [diff] [blame] | 197 | assert((size_t)rn.size == outsize); |
Lev Walkin | 5fe72e9 | 2012-01-07 17:00:29 -0800 | [diff] [blame] | 198 | } |
| 199 | assert(memcmp(rn.buf, outbuf, rn.size) == 0); |
| 200 | |
Lev Walkin | 5fda7d5 | 2012-01-09 03:20:19 -0800 | [diff] [blame] | 201 | check_str_representation(d, sample, canonical_sample, lineno); |
Lev Walkin | 5fe72e9 | 2012-01-07 17:00:29 -0800 | [diff] [blame] | 202 | } |
| 203 | |
| 204 | static void |
Lev Walkin | 5fda7d5 | 2012-01-09 03:20:19 -0800 | [diff] [blame] | 205 | check_ber_buffer_oneway(double d, const char *sample, const char *canonical_sample, uint8_t *buf, size_t bufsize, int lineno) { |
Lev Walkin | 5fe72e9 | 2012-01-07 17:00:29 -0800 | [diff] [blame] | 206 | REAL_t rn; |
| 207 | double val; |
| 208 | uint8_t *p, *end; |
| 209 | int ret; |
| 210 | |
| 211 | memset(&rn, 0, sizeof(rn)); |
| 212 | |
| 213 | printf("verify double value %.12f [", d); |
| 214 | for(p = (uint8_t *)&d, end = p + sizeof(double); p < end ; p++) |
| 215 | printf("%02x", *p); |
| 216 | printf("] (ilogb %d)\n", ilogb(d)); |
| 217 | |
| 218 | |
| 219 | ret = asn_double2REAL(&rn, d); |
| 220 | assert(ret == 0); |
| 221 | |
| 222 | printf("canonical DER: ["); |
| 223 | for(p = rn.buf, end = p + rn.size; p < end; p++) |
| 224 | printf("%02x", *p); |
| 225 | printf("]\n"); |
| 226 | |
| 227 | rn.buf = buf; |
| 228 | rn.size = bufsize; |
| 229 | |
| 230 | printf("received as: ["); |
| 231 | for(p = rn.buf, end = p + rn.size; p < end; p++) |
| 232 | printf("%02x", *p); |
| 233 | printf("]\n"); |
| 234 | |
| 235 | ret = asn_REAL2double(&rn, &val); |
| 236 | assert(ret == 0); |
| 237 | |
| 238 | printf("%.12f vs %.12f\n", d, val); |
| 239 | |
| 240 | assert(val == d); |
| 241 | |
Lev Walkin | 5fda7d5 | 2012-01-09 03:20:19 -0800 | [diff] [blame] | 242 | check_str_representation(val, sample, canonical_sample, lineno); |
Lev Walkin | 5fe72e9 | 2012-01-07 17:00:29 -0800 | [diff] [blame] | 243 | } |
| 244 | |
Lev Walkin | e8727ec | 2012-01-09 05:46:16 -0800 | [diff] [blame] | 245 | /* |
| 246 | * 8.5.7 Verify binary encoding, two-way. |
| 247 | */ |
| 248 | static void |
| 249 | check_ber_857_encoding(int base, int sign, int scaling_factor, int exponent, int mantissa) { |
| 250 | uint8_t buf[100]; |
| 251 | uint8_t *b = buf; |
| 252 | int explen, mantlen; |
| 253 | REAL_t rn; |
| 254 | static REAL_t rn_check; |
| 255 | double d; |
| 256 | double verify; |
| 257 | int baseF = 0; |
| 258 | int ret; |
| 259 | |
| 260 | #define BIT(b) (1<<(b - 1)) |
| 261 | |
| 262 | switch(base) { |
| 263 | case 0: baseF = 1; break; |
| 264 | case 1: baseF = 3; break; |
| 265 | case 2: baseF = 4; break; |
| 266 | default: assert(base >= 0 && base <= 2); |
| 267 | } |
| 268 | |
| 269 | if(exponent >= -128 && exponent <= 127) { |
| 270 | explen = 1; |
| 271 | } else { |
| 272 | assert(exponent > -60000 && exponent < 60000); |
| 273 | explen = 2; |
| 274 | } |
| 275 | |
| 276 | if(mantissa == 0) { |
| 277 | mantlen = 0; |
| 278 | } else if(mantissa >= 0 && mantissa <= 255) { |
| 279 | mantlen = 1; |
| 280 | } else if(mantissa >= 0 && mantissa <= 65535) { |
| 281 | mantlen = 2; |
| 282 | } else { |
| 283 | assert(mantissa >= 0 && mantissa <= 256 * 65536); |
| 284 | mantlen = 3; |
| 285 | } |
| 286 | |
| 287 | *b = BIT(8) | (sign ? BIT(7) : 0); |
| 288 | *b |= (base & 0x03) << 4; /* 8.5.7.2 */ |
| 289 | *b |= (scaling_factor & 0x03) << 2; /* 8.5.7.3 */ |
| 290 | *b |= ((explen - 1) & 0x03); /* 8.5.7.4 */ |
| 291 | b++; |
| 292 | switch(explen) { |
| 293 | case 2: *b++ = (int8_t)(exponent >> 8); |
| 294 | case 1: *b++ = (int8_t)exponent; |
| 295 | } |
| 296 | switch(mantlen) { |
| 297 | case 3: *b++ = (mantissa >> 16) & 0xff; |
| 298 | case 2: *b++ = (mantissa >> 8) & 0xff; |
| 299 | case 1: *b++ = (mantissa & 0xff); |
| 300 | } |
| 301 | |
| 302 | verify = (sign ? -1.0 : 1.0) * ldexp(mantissa, exponent * baseF + scaling_factor); |
| 303 | |
| 304 | /* Verify than encoding of this double value round-trips */ |
| 305 | if(!isinf(verify)) { |
| 306 | d = verify; |
| 307 | verify = 0.0; |
| 308 | ret = asn_double2REAL(&rn_check, d); |
| 309 | assert(ret == 0); |
| 310 | ret = asn_REAL2double(&rn_check, &verify); |
| 311 | assert(ret == 0); |
| 312 | assert(d == verify); |
| 313 | |
| 314 | /* Verify with a slight non-friendly offset. Not too easy. */ |
| 315 | d = verify - 0.13; |
| 316 | verify = 0.0; |
| 317 | ret = asn_double2REAL(&rn_check, d); |
| 318 | assert(ret == 0); |
| 319 | ret = asn_REAL2double(&rn_check, &verify); |
| 320 | assert(ret == 0); |
| 321 | assert(ret == 0); |
| 322 | assert(d == verify); |
| 323 | } |
| 324 | |
| 325 | verify = (sign ? -1.0 : 1.0) * ldexp(mantissa, exponent * baseF + scaling_factor); |
| 326 | |
| 327 | rn.buf = buf; |
| 328 | rn.size = b - buf; |
| 329 | ret = asn_REAL2double(&rn, &d); |
| 330 | if(!isinf(verify) && (ret != 0 || d != verify)) { |
| 331 | printf("Converting B=%d, S=%d, F=%d, E=%d/%d, M=%d/%d\n", (1 << baseF), sign, scaling_factor, exponent, explen, mantissa, mantlen); |
| 332 | printf("Verify: %e\n", verify); |
| 333 | uint8_t *p; |
| 334 | printf("received as: ["); |
| 335 | for(p = buf; p < b; p++) printf("%02x", *p); |
| 336 | printf("]\n"); |
| 337 | assert(ret == 0); |
| 338 | printf("Converted: %e\n", d); |
| 339 | assert(d == verify); |
| 340 | } |
| 341 | } |
Lev Walkin | 5fe72e9 | 2012-01-07 17:00:29 -0800 | [diff] [blame] | 342 | |
| 343 | static void |
| 344 | check_ber_encoding() { |
| 345 | static const double zero = 0.0; |
| 346 | |
Lev Walkin | 5fda7d5 | 2012-01-09 03:20:19 -0800 | [diff] [blame] | 347 | #define CHECK_BER_STRICT(v, nocan, can, inbuf, outbuf) \ |
| 348 | check_ber_buffer_twoway(v, nocan, can, inbuf, sizeof(inbuf), \ |
| 349 | outbuf, sizeof(outbuf), __LINE__) |
Lev Walkin | 5fe72e9 | 2012-01-07 17:00:29 -0800 | [diff] [blame] | 350 | |
| 351 | #define CHECK_BER_NONSTRICT(v, nocan, can, buf) \ |
Lev Walkin | 5fda7d5 | 2012-01-09 03:20:19 -0800 | [diff] [blame] | 352 | check_ber_buffer_oneway(v, nocan, can, buf, sizeof(buf), __LINE__) |
Lev Walkin | 5fe72e9 | 2012-01-07 17:00:29 -0800 | [diff] [blame] | 353 | |
| 354 | /* |
| 355 | * X.690 8.4 Encoding of an enumerated value. |
| 356 | */ |
| 357 | |
| 358 | /* 8.5.2 If the real value is the value plus zero, |
| 359 | * there shall be no contents octet in the encoding */ |
| 360 | { uint8_t b_0[] = {}; |
Lev Walkin | 5fda7d5 | 2012-01-09 03:20:19 -0800 | [diff] [blame] | 361 | CHECK_BER_STRICT(0.0, "0", "0", b_0, b_0); } |
Lev Walkin | 5fe72e9 | 2012-01-07 17:00:29 -0800 | [diff] [blame] | 362 | |
| 363 | /* 8.5.3 When -0 is to be encoded, there shall be only one contents octet */ |
| 364 | { uint8_t b_m0[] = { 0x43 }; |
Lev Walkin | 5fda7d5 | 2012-01-09 03:20:19 -0800 | [diff] [blame] | 365 | CHECK_BER_STRICT(-0.0, "-0", "-0", b_m0, b_m0); } |
Lev Walkin | 5fe72e9 | 2012-01-07 17:00:29 -0800 | [diff] [blame] | 366 | |
| 367 | /* Old way of encoding -0.0: 8.5.6 a) */ |
| 368 | { uint8_t b_m0[] = { 0x43 }; |
| 369 | uint8_t b_m0_856a[] = { 0xC0, 0x00 }; /* #8.5.6 a) */ |
| 370 | uint8_t b_m0_856a_1[] = { 0xC0, 0x00, 0x00 }; |
| 371 | uint8_t b_m0_856a_2[] = { 0xC0, 0x00, 0x00, 0x00 }; |
| 372 | uint8_t b_m0_856a_3[] = { 0xC0, 0x00, 0x00, 0x00, 0x00 }; |
| 373 | CHECK_BER_STRICT(-0.0, "-0", "-0", b_m0_856a, b_m0); |
| 374 | CHECK_BER_STRICT(-0.0, "-0", "-0", b_m0_856a_1, b_m0); |
| 375 | CHECK_BER_STRICT(-0.0, "-0", "-0", b_m0_856a_2, b_m0); |
Lev Walkin | 5fda7d5 | 2012-01-09 03:20:19 -0800 | [diff] [blame] | 376 | CHECK_BER_STRICT(-0.0, "-0", "-0", b_m0_856a_3, b_m0); } |
Lev Walkin | 5fe72e9 | 2012-01-07 17:00:29 -0800 | [diff] [blame] | 377 | |
| 378 | /* 8.5.6 c) => 8.5.9 SpecialRealValue */ |
| 379 | { uint8_t b_pinf[] = { 0x40 }; |
| 380 | uint8_t b_minf[] = { 0x41 }; |
| 381 | uint8_t b_nan[] = { 0x42 }; |
| 382 | CHECK_BER_STRICT(1.0/zero, "<PLUS-INFINITY/>", "<PLUS-INFINITY/>", b_pinf, b_pinf); |
| 383 | CHECK_BER_STRICT(-1.0/zero, "<MINUS-INFINITY/>", "<MINUS-INFINITY/>", b_minf, b_minf); |
Lev Walkin | 5fda7d5 | 2012-01-09 03:20:19 -0800 | [diff] [blame] | 384 | CHECK_BER_STRICT(zero/zero, "<NOT-A-NUMBER/>", "<NOT-A-NUMBER/>", b_nan, b_nan); } |
| 385 | |
| 386 | /* 8.5.6 b) => 8.5.8 Decimal encoding is used; NR1 form */ |
| 387 | { uint8_t b_0_nr1[] = { 0x01, '0' }; |
| 388 | uint8_t b_0[] = { }; |
| 389 | CHECK_BER_STRICT(0.0, "0", "0", b_0_nr1, b_0); } |
| 390 | { uint8_t b_0_nr1[] = { 0x01, '0', '0' }; |
| 391 | uint8_t b_0[] = { }; |
| 392 | CHECK_BER_STRICT(0.0, "0", "0", b_0_nr1, b_0); } |
| 393 | { uint8_t b_0_nr1[] = { 0x01, ' ', '0' }; |
| 394 | uint8_t b_0[] = { }; |
| 395 | CHECK_BER_STRICT(0.0, "0", "0", b_0_nr1, b_0); } |
| 396 | { uint8_t b_p0_nr1[] = { 0x01, '+', '0' }; |
| 397 | uint8_t b_0[] = { }; |
| 398 | CHECK_BER_STRICT(0.0, "0", "0", b_p0_nr1, b_0); } |
| 399 | { uint8_t b_p0_nr1[] = { 0x01, ' ', '+', '0' }; |
| 400 | uint8_t b_0[] = { }; |
| 401 | CHECK_BER_STRICT(0.0, "0", "0", b_p0_nr1, b_0); } |
| 402 | { uint8_t b_m0_nr1[] = { 0x01, '-', '0' }; |
| 403 | uint8_t b_m0[] = { 0x43 }; |
| 404 | CHECK_BER_STRICT(-0.0, "-0", "-0", b_m0_nr1, b_m0); } |
| 405 | { uint8_t b_m0_nr1[] = { 0x01, ' ', '-', '0' }; |
| 406 | uint8_t b_m0[] = { 0x43 }; |
| 407 | CHECK_BER_STRICT(-0.0, "-0", "-0", b_m0_nr1, b_m0); } |
| 408 | |
| 409 | { uint8_t b_1_nr1[] = { 0x01, '1' }; |
| 410 | uint8_t b_1[] = { 0x80, 0x00, 0x01 }; |
| 411 | CHECK_BER_STRICT(1.0, "1.0", "1.0E0", b_1_nr1, b_1); } |
| 412 | { uint8_t b_1_nr1[] = { 0x01, '0', '1' }; |
| 413 | uint8_t b_1[] = { 0x80, 0x00, 0x01 }; |
| 414 | CHECK_BER_STRICT(1.0, "1.0", "1.0E0", b_1_nr1, b_1); } |
| 415 | { uint8_t b_1_nr1[] = { 0x01, ' ', '1' }; |
| 416 | uint8_t b_1[] = { 0x80, 0x00, 0x01 }; |
| 417 | CHECK_BER_STRICT(1.0, "1.0", "1.0E0", b_1_nr1, b_1); } |
| 418 | { uint8_t b_p1_nr1[] = { 0x01, '+', '1' }; |
| 419 | uint8_t b_1[] = { 0x80, 0x00, 0x01 }; |
| 420 | CHECK_BER_STRICT(1.0, "1.0", "1.0E0", b_p1_nr1, b_1); } |
| 421 | { uint8_t b_p1_nr1[] = { 0x01, ' ', '+', '1' }; |
| 422 | uint8_t b_1[] = { 0x80, 0x00, 0x01 }; |
| 423 | CHECK_BER_STRICT(1.0, "1.0", "1.0E0", b_p1_nr1, b_1); } |
| 424 | { uint8_t b_m1_nr1[] = { 0x01, '-', '1' }; |
| 425 | uint8_t b_m1[] = { 0xC0, 0x00, 0x01 }; |
| 426 | CHECK_BER_STRICT(-1.0, "-1.0", "-1.0E0", b_m1_nr1, b_m1); } |
| 427 | { uint8_t b_m1_nr1[] = { 0x01, ' ', '-', '1' }; |
| 428 | uint8_t b_m1[] = { 0xC0, 0x00, 0x01 }; |
| 429 | CHECK_BER_STRICT(-1.0, "-1.0", "-1.0E0", b_m1_nr1, b_m1); } |
| 430 | |
| 431 | { |
| 432 | uint8_t comma_symbol[] = { '.', ',' }; |
| 433 | int csi; |
| 434 | for(csi = 0; csi < 2; csi++) { |
| 435 | uint8_t CS = comma_symbol[csi]; |
| 436 | |
| 437 | /* 8.5.6 b) => 8.5.8 Decimal encoding is used; NR2 form */ |
| 438 | { uint8_t b_0_nr2[] = { 0x02, '0', CS, '0' }; |
| 439 | uint8_t b_0[] = { }; |
| 440 | CHECK_BER_STRICT(0.0, "0", "0", b_0_nr2, b_0); } |
| 441 | { uint8_t b_0_nr2[] = { 0x02, '0', '0', CS, '0' }; |
| 442 | uint8_t b_0[] = { }; |
| 443 | CHECK_BER_STRICT(0.0, "0", "0", b_0_nr2, b_0); } |
| 444 | { uint8_t b_0_nr2[] = { 0x02, ' ', '0', CS, '0' }; |
| 445 | uint8_t b_0[] = { }; |
| 446 | CHECK_BER_STRICT(0.0, "0", "0", b_0_nr2, b_0); } |
| 447 | { uint8_t b_p0_nr2[] = { 0x02, '+', '0', CS, '0' }; |
| 448 | uint8_t b_0[] = { }; |
| 449 | CHECK_BER_STRICT(0.0, "0", "0", b_p0_nr2, b_0); } |
| 450 | { uint8_t b_p0_nr2[] = { 0x02, ' ', '+', '0', CS, '0' }; |
| 451 | uint8_t b_0[] = { }; |
| 452 | CHECK_BER_STRICT(0.0, "0", "0", b_p0_nr2, b_0); } |
| 453 | { uint8_t b_m0_nr2[] = { 0x02, '-', '0', CS, '0' }; |
| 454 | uint8_t b_m0[] = { 0x43 }; |
| 455 | CHECK_BER_STRICT(-0.0, "-0", "-0", b_m0_nr2, b_m0); } |
| 456 | { uint8_t b_m0_nr2[] = { 0x02, ' ', '-', '0', CS, '0' }; |
| 457 | uint8_t b_m0[] = { 0x43 }; |
| 458 | CHECK_BER_STRICT(-0.0, "-0", "-0", b_m0_nr2, b_m0); } |
| 459 | |
| 460 | /* 8.5.6 b) => 8.5.8 NR2 "1." */ |
| 461 | { uint8_t b_1_nr2[] = { 0x02, '1', CS }; |
| 462 | uint8_t b_1[] = { 0x80, 0x00, 0x01 }; |
| 463 | CHECK_BER_STRICT(1.0, "1.0", "1.0E0", b_1_nr2, b_1); } |
| 464 | { uint8_t b_1_nr2[] = { 0x02, '0', '1', CS }; |
| 465 | uint8_t b_1[] = { 0x80, 0x00, 0x01 }; |
| 466 | CHECK_BER_STRICT(1.0, "1.0", "1.0E0", b_1_nr2, b_1); } |
| 467 | { uint8_t b_1_nr2[] = { 0x02, ' ', '1', CS }; |
| 468 | uint8_t b_1[] = { 0x80, 0x00, 0x01 }; |
| 469 | CHECK_BER_STRICT(1.0, "1.0", "1.0E0", b_1_nr2, b_1); } |
| 470 | { uint8_t b_p1_nr2[] = { 0x02, '+', '1', CS }; |
| 471 | uint8_t b_1[] = { 0x80, 0x00, 0x01 }; |
| 472 | CHECK_BER_STRICT(1.0, "1.0", "1.0E0", b_p1_nr2, b_1); } |
| 473 | { uint8_t b_p1_nr2[] = { 0x02, ' ', '+', '1', CS }; |
| 474 | uint8_t b_1[] = { 0x80, 0x00, 0x01 }; |
| 475 | CHECK_BER_STRICT(1.0, "1.0", "1.0E0", b_p1_nr2, b_1); } |
| 476 | { uint8_t b_m1_nr2[] = { 0x02, '-', '1', CS }; |
| 477 | uint8_t b_m1[] = { 0xC0, 0x00, 0x01 }; |
| 478 | CHECK_BER_STRICT(-1.0, "-1.0", "-1.0E0", b_m1_nr2, b_m1); } |
| 479 | { uint8_t b_m1_nr2[] = { 0x02, ' ', '-', '1', CS }; |
| 480 | uint8_t b_m1[] = { 0xC0, 0x00, 0x01 }; |
| 481 | CHECK_BER_STRICT(-1.0, "-1.0", "-1.0E0", b_m1_nr2, b_m1); } |
| 482 | |
| 483 | /* 8.5.6 b) => 8.5.8 NR2 ".5" */ |
| 484 | { uint8_t b_05_nr2[] = { 0x02, CS, '5' }; |
| 485 | uint8_t b_05[] = { 0x80, 0xff, 0x01 }; |
| 486 | CHECK_BER_STRICT(0.5, "0.5", "5.0E-1", b_05_nr2, b_05); } |
| 487 | { uint8_t b_05_nr2[] = { 0x02, '0', CS, '5' }; |
| 488 | uint8_t b_05[] = { 0x80, 0xff, 0x01 }; |
| 489 | CHECK_BER_STRICT(0.5, "0.5", "5.0E-1", b_05_nr2, b_05); } |
| 490 | { uint8_t b_05_nr2[] = { 0x02, ' ', CS, '5' }; |
| 491 | uint8_t b_05[] = { 0x80, 0xff, 0x01 }; |
| 492 | CHECK_BER_STRICT(0.5, "0.5", "5.0E-1", b_05_nr2, b_05); } |
| 493 | { uint8_t b_p1_nr2[] = { 0x02, '+', CS, '5' }; |
| 494 | uint8_t b_05[] = { 0x80, 0xff, 0x01 }; |
| 495 | CHECK_BER_STRICT(0.5, "0.5", "5.0E-1", b_p1_nr2, b_05); } |
| 496 | { uint8_t b_p1_nr2[] = { 0x02, ' ', '+', CS, '5' }; |
| 497 | uint8_t b_05[] = { 0x80, 0xff, 0x01 }; |
| 498 | CHECK_BER_STRICT(0.5, "0.5", "5.0E-1", b_p1_nr2, b_05); } |
| 499 | { uint8_t b_m05_nr2[] = { 0x02, '-', CS, '5' }; |
| 500 | uint8_t b_m05[] = { 0xC0, 0xff, 0x01 }; |
| 501 | CHECK_BER_STRICT(-0.5, "-0.5", "-5.0E-1", b_m05_nr2, b_m05); } |
| 502 | { uint8_t b_m05_nr2[] = { 0x02, ' ', '-', CS, '5' }; |
| 503 | uint8_t b_m05[] = { 0xC0, 0xff, 0x01 }; |
| 504 | CHECK_BER_STRICT(-0.5, "-0.5", "-5.0E-1", b_m05_nr2, b_m05); } |
| 505 | |
| 506 | /* 8.5.6 b) => 8.5.8 Decimal encoding is used; NR3 form */ |
| 507 | { uint8_t b_0_nr3[] = { 0x03, '0', CS, '0', 'e', '0' }; |
| 508 | uint8_t b_0[] = { }; |
| 509 | CHECK_BER_STRICT(0.0, "0", "0", b_0_nr3, b_0); } |
| 510 | { uint8_t b_0_nr3[] = { 0x03, '0', '0', CS, '0', 'E', '0' }; |
| 511 | uint8_t b_0[] = { }; |
| 512 | CHECK_BER_STRICT(0.0, "0", "0", b_0_nr3, b_0); } |
| 513 | { uint8_t b_0_nr3[] = { 0x03, ' ', '0', CS, '0', 'e', '0' }; |
| 514 | uint8_t b_0[] = { }; |
| 515 | CHECK_BER_STRICT(0.0, "0", "0", b_0_nr3, b_0); } |
| 516 | { uint8_t b_p0_nr3[] = { 0x03, '+', '0', CS, '0', 'E', '+', '0' }; |
| 517 | uint8_t b_0[] = { }; |
| 518 | CHECK_BER_STRICT(0.0, "0", "0", b_p0_nr3, b_0); } |
| 519 | { uint8_t b_p0_nr3[] = { 0x03, ' ', '+', '0', CS, '0', 'e', '+', '0' }; |
| 520 | uint8_t b_0[] = { }; |
| 521 | CHECK_BER_STRICT(0.0, "0", "0", b_p0_nr3, b_0); } |
| 522 | { uint8_t b_m0_nr3[] = { 0x03, '-', '0', CS, '0', 'E', '-', '0' }; |
| 523 | uint8_t b_m0[] = { 0x43 }; |
| 524 | CHECK_BER_STRICT(-0.0, "-0", "-0", b_m0_nr3, b_m0); } |
| 525 | { uint8_t b_m0_nr3[] = { 0x03, ' ', '-', '0', CS, '0', 'e', '-', '0' }; |
| 526 | uint8_t b_m0[] = { 0x43 }; |
| 527 | CHECK_BER_STRICT(-0.0, "-0", "-0", b_m0_nr3, b_m0); } |
| 528 | |
| 529 | /* 8.5.6 b) => 8.5.8 NR3 "5.e-1" */ |
| 530 | { uint8_t b_5_nr3[] = { 0x03, '5', CS, 'e', '-', '1' }; |
| 531 | uint8_t b_5[] = { 0x80, 0xff, 0x01 }; |
| 532 | CHECK_BER_STRICT(0.5, "0.5", "5.0E-1", b_5_nr3, b_5); } |
| 533 | { uint8_t b_5_nr3[] = { 0x03, '0', '5', CS, 'E', '-', '1' }; |
| 534 | uint8_t b_5[] = { 0x80, 0xff, 0x01 }; |
| 535 | CHECK_BER_STRICT(0.5, "0.5", "5.0E-1", b_5_nr3, b_5); } |
| 536 | { uint8_t b_5_nr3[] = { 0x03, ' ', '5', CS, 'e', '-', '1' }; |
| 537 | uint8_t b_5[] = { 0x80, 0xff, 0x01 }; |
| 538 | CHECK_BER_STRICT(0.5, "0.5", "5.0E-1", b_5_nr3, b_5); } |
| 539 | { uint8_t b_p5_nr3[] = { 0x03, '+', '5', CS, 'E', '-', '1' }; |
| 540 | uint8_t b_5[] = { 0x80, 0xff, 0x01 }; |
| 541 | CHECK_BER_STRICT(0.5, "0.5", "5.0E-1", b_p5_nr3, b_5); } |
| 542 | { uint8_t b_p5_nr3[] = { 0x03, ' ', '+', '5', CS, 'e', '-', '1' }; |
| 543 | uint8_t b_5[] = { 0x80, 0xff, 0x01 }; |
| 544 | CHECK_BER_STRICT(0.5, "0.5", "5.0E-1", b_p5_nr3, b_5); } |
| 545 | { uint8_t b_m5_nr3[] = { 0x03, '-', '5', CS, 'E', '-', '1' }; |
| 546 | uint8_t b_m5[] = { 0xC0, 0xff, 0x01 }; |
| 547 | CHECK_BER_STRICT(-0.5, "-0.5", "-5.0E-1", b_m5_nr3, b_m5); } |
| 548 | { uint8_t b_m5_nr3[] = { 0x03, ' ', '-', '5', CS, 'e', '-', '1' }; |
| 549 | uint8_t b_m5[] = { 0xC0, 0xff, 0x01 }; |
| 550 | CHECK_BER_STRICT(-0.5, "-0.5", "-5.0E-1", b_m5_nr3, b_m5); } |
| 551 | |
| 552 | /* 8.5.6 b) => 8.5.8 NR3 ".5e1" */ |
| 553 | { uint8_t b_05_nr3[] = { 0x03, CS, '5', 'e', '+', '1' }; |
| 554 | uint8_t b_05[] = { 0x80, 0x00, 0x05 }; |
| 555 | CHECK_BER_STRICT(5.0, "5.0", "5.0E0", b_05_nr3, b_05); } |
| 556 | { uint8_t b_05_nr3[] = { 0x03, '0', CS, '5', 'E', '+', '1'}; |
| 557 | uint8_t b_05[] = { 0x80, 0x00, 0x05 }; |
| 558 | CHECK_BER_STRICT(5.0, "5.0", "5.0E0", b_05_nr3, b_05); } |
| 559 | { uint8_t b_05_nr3[] = { 0x03, ' ', CS, '5', 'e', '1'}; |
| 560 | uint8_t b_05[] = { 0x80, 0x00, 0x05 }; |
| 561 | CHECK_BER_STRICT(5.0, "5.0", "5.0E0", b_05_nr3, b_05); } |
| 562 | { uint8_t b_p1_nr3[] = { 0x03, '+', CS, '5', 'E', '1' }; |
| 563 | uint8_t b_05[] = { 0x80, 0x00, 0x05 }; |
| 564 | CHECK_BER_STRICT(5.0, "5.0", "5.0E0", b_p1_nr3, b_05); } |
| 565 | { uint8_t b_p1_nr3[] = { 0x03, ' ', '+', CS, '5', 'e', '+', '1' }; |
| 566 | uint8_t b_05[] = { 0x80, 0x00, 0x05 }; |
| 567 | CHECK_BER_STRICT(5.0, "5.0", "5.0E0", b_p1_nr3, b_05); } |
| 568 | { uint8_t b_m05_nr3[] = { 0x03, '-', CS, '5', 'E', '+', '1' }; |
| 569 | uint8_t b_m05[] = { 0xC0, 0x00, 0x05 }; |
| 570 | CHECK_BER_STRICT(-5.0, "-5.0", "-5.0E0", b_m05_nr3, b_m05); } |
| 571 | { uint8_t b_m05_nr3[] = { 0x03, ' ', '-', CS, '5', 'e', '1' }; |
| 572 | uint8_t b_m05[] = { 0xC0, 0x00, 0x05 }; |
| 573 | CHECK_BER_STRICT(-5.0, "-5.0", "-5.0E0", b_m05_nr3, b_m05); } |
| 574 | } /* for(comma symbol) */ |
| 575 | } |
Lev Walkin | 5fe72e9 | 2012-01-07 17:00:29 -0800 | [diff] [blame] | 576 | |
Lev Walkin | e8727ec | 2012-01-09 05:46:16 -0800 | [diff] [blame] | 577 | /* Scan through the range of bits, construct the valid base-2 numbers, and |
| 578 | * try two-way conversion with them */ |
| 579 | { |
| 580 | int base, sign, scaling_factor, exponent, mantissa; |
| 581 | for(base = 0; base <= 2; base++) { |
| 582 | for(sign = 0; sign <= 1; sign++) { |
| 583 | for(scaling_factor = 0; scaling_factor <= 3; scaling_factor++) { |
| 584 | for(exponent = -1000; exponent < 1000; exponent += (exponent > -990 && exponent < 990) ? 100 : 1) { |
| 585 | for(mantissa = 0; mantissa < 66000; mantissa += (mantissa > 300 && mantissa < 65400) ? 100 : 1) { |
| 586 | check_ber_857_encoding(base, sign, scaling_factor, exponent, mantissa); |
| 587 | } |
| 588 | } |
| 589 | } |
| 590 | } |
| 591 | } |
| 592 | } |
| 593 | |
Lev Walkin | 5fe72e9 | 2012-01-07 17:00:29 -0800 | [diff] [blame] | 594 | { |
| 595 | uint8_t b_1_0[] = |
| 596 | { 0x80, 0xcc, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; |
| 597 | uint8_t b_1_1[] = |
| 598 | { 0x80, 0xcc, 0x11, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a }; |
| 599 | uint8_t b_3_14[] = |
| 600 | { 0x80, 0xcd, 0x19, 0x1e, 0xb8, 0x51, 0xeb, 0x85, 0x1f }; |
| 601 | uint8_t b_3_14_mo1[] = |
| 602 | { 0xC0, 0xc5, 0x19, 0x1e, 0xb8, 0x51, 0xeb, 0x85, 0x1f,3}; |
| 603 | uint8_t b_3_14_mo2[] = |
| 604 | { 0x80, 0xbd, 0x19, 0x1e, 0xb8, 0x51, 0xeb, 0x85, 0x1f,3,2}; |
| 605 | |
| 606 | CHECK_BER_NONSTRICT(1.0, "1.0", "1.0E0", b_1_0); |
| 607 | CHECK_BER_NONSTRICT(1.1, "1.1", "1.1E0", b_1_1); |
| 608 | CHECK_BER_NONSTRICT(3.14, "3.14", "3.14E0", b_3_14); |
| 609 | /* These two are very interesting! They check mantissa overflow! */ |
| 610 | CHECK_BER_NONSTRICT(-3.14, "-3.14", "-3.14E0", b_3_14_mo1); |
| 611 | CHECK_BER_NONSTRICT(3.14, "3.14", "3.14E0", b_3_14_mo2); |
| 612 | } |
| 613 | } |
Lev Walkin | f0b808d | 2005-04-25 21:08:25 +0000 | [diff] [blame] | 614 | |
Lev Walkin | 41ba1f2 | 2004-09-14 12:46:35 +0000 | [diff] [blame] | 615 | int |
| 616 | main() { |
| 617 | REAL_t rn; |
Lev Walkin | c51e7d6 | 2004-09-27 22:16:18 +0000 | [diff] [blame] | 618 | static const double zero = 0.0; |
Lev Walkin | 41ba1f2 | 2004-09-14 12:46:35 +0000 | [diff] [blame] | 619 | memset(&rn, 0, sizeof(rn)); |
| 620 | |
Lev Walkin | 5fe72e9 | 2012-01-07 17:00:29 -0800 | [diff] [blame] | 621 | check_ber_encoding(); |
| 622 | |
Lev Walkin | ed46543 | 2004-09-27 20:52:36 +0000 | [diff] [blame] | 623 | check(&rn, 0.0, "0", "0"); |
| 624 | check(&rn, -0.0, "-0", "-0"); /* minus-zero */ |
Lev Walkin | c51e7d6 | 2004-09-27 22:16:18 +0000 | [diff] [blame] | 625 | check(&rn, zero/zero, "<NOT-A-NUMBER/>", "<NOT-A-NUMBER/>"); |
| 626 | check(&rn, 1.0/zero, "<PLUS-INFINITY/>", "<PLUS-INFINITY/>"); |
| 627 | check(&rn, -1.0/zero, "<MINUS-INFINITY/>", "<MINUS-INFINITY/>"); |
Lev Walkin | ed46543 | 2004-09-27 20:52:36 +0000 | [diff] [blame] | 628 | check(&rn, 1.0, "1.0", "1.0E0"); |
| 629 | check(&rn, -1.0, "-1.0", "-1.0E0"); |
Lev Walkin | ed46543 | 2004-09-27 20:52:36 +0000 | [diff] [blame] | 630 | check(&rn, 0.1, "0.1", "1.0E-1"); |
Lev Walkin | f0b808d | 2005-04-25 21:08:25 +0000 | [diff] [blame] | 631 | check(&rn, 0.01, "0.01", "1.0E-2"); |
| 632 | check(&rn, 0.02, "0.02", "2.0E-2"); |
| 633 | check(&rn, 0.09, "0.09", "9.0E-2"); |
| 634 | check(&rn, 1.5, "1.5", "1.5E0"); |
Lev Walkin | ed46543 | 2004-09-27 20:52:36 +0000 | [diff] [blame] | 635 | check(&rn, 0.33333, "0.33333", "3.3333E-1"); |
| 636 | check(&rn, 2, "2.0", "2.0E0"); |
| 637 | check(&rn, 2.1, "2.1", "2.1E0"); |
| 638 | check(&rn, 3, "3.0", "3.0E0"); |
| 639 | check(&rn, 3.1, "3.1", "3.1E0"); |
| 640 | check(&rn, 3.14, "3.14", "3.14E0"); |
| 641 | check(&rn, 3.1415, "3.1415", "3.1415E0"); |
| 642 | check(&rn, 3.141592, "3.141592", "3.141592E0"); |
| 643 | check(&rn, 3.14159265, "3.14159265", "3.14159265E0"); |
| 644 | check(&rn, -3.14159265, "-3.14159265", "-3.14159265E0"); |
| 645 | check(&rn, 14159265.0, "14159265.0", "1.4159265E7"); |
| 646 | check(&rn, -123456789123456789.0, "-123456789123456784.0", "-1.234567891234568E17"); |
Lev Walkin | f0b808d | 2005-04-25 21:08:25 +0000 | [diff] [blame] | 647 | check(&rn, 0.00000000001, "0.00000000001", "9.999999999999999E-12"); |
| 648 | check(&rn, 0.00000000002, "0.00000000002", "2.0E-11"); |
| 649 | check(&rn, 0.00000000009, "0.00000000009", "9.0E-11"); |
| 650 | check(&rn, 0.000000000002, "0.000000000002", "2.0E-12"); |
| 651 | check(&rn, 0.0000000000002, "0.0000000000002", "2.0E-13"); |
| 652 | check(&rn, 0.00000000000002, "0.00000000000002", "2.0E-14"); |
| 653 | check(&rn, 0.000000000000002, "0.000000000000002", "2.0E-15"); |
| 654 | check(&rn, 0.0000000000000002, "0.0", "2.0E-16"); |
Lev Walkin | ed46543 | 2004-09-27 20:52:36 +0000 | [diff] [blame] | 655 | check(&rn, 0.0000000000000000000001, "0.0", "1.0E-22"); |
| 656 | check(&rn, 0.000000000000000000000000000001, "0.0", "1.0E-30"); /* proved 2B a problem */ |
| 657 | check(&rn,-0.000000000000000000000000000001, "-0.0", "-1.0E-30"); /* proved 2B a problem */ |
| 658 | check(&rn, 0.0000000000010000000001000000000001, 0, 0); |
| 659 | check(&rn, 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 0, 0); |
| 660 | check(&rn, 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 0, 0); |
| 661 | check(&rn,-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 0, 0); |
| 662 | check(&rn,-3.33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333, 0, 0); |
| 663 | check(&rn, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000033333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333, 0, 0); |
Lev Walkin | 8ca13c8 | 2016-01-24 22:40:00 -0800 | [diff] [blame] | 664 | check(&rn, 0.25, "0.25", "2.5E-1"); |
| 665 | check(&rn, -0.25, "-0.25", "-2.5E-1"); |
| 666 | check(&rn, 0.03, "0.03", "3.0E-2"); |
| 667 | check(&rn, -0.03, "-0.03", "-3.0E-2"); |
| 668 | |
| 669 | check(&rn, 4.01E-50, "0.0", "4.01E-50"); |
| 670 | check(&rn, -4.01E-50, "-0.0", "-4.01E-50"); |
| 671 | check(&rn, -4.9406564584124654E-324, "-0.0", "-4.940656458412465E-324"); /* MIN */ |
| 672 | check(&rn, DBL_MIN, "0.0", "2.225073858507201E-308"); /* MIN */ |
| 673 | check(&rn, -DBL_MIN, "-0.0", "-2.225073858507201E-308"); /* -MIN */ |
| 674 | check(&rn, DBL_MAX, "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0", "1.797693134862316E308"); /* MAX */ |
| 675 | check(&rn, -DBL_MAX, "-179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0", "-1.797693134862316E308"); /* MAX */ |
| 676 | check(&rn, -DBL_TRUE_MIN, "-0.0", "-4.940656458412465E-324"); /* subnorm */ |
| 677 | check(&rn, DBL_TRUE_MIN, "0.0", "4.940656458412465E-324"); /* subnorm */ |
Lev Walkin | 41ba1f2 | 2004-09-14 12:46:35 +0000 | [diff] [blame] | 678 | |
Lev Walkin | 5f56091 | 2004-10-21 13:37:57 +0000 | [diff] [blame] | 679 | |
Lev Walkin | 1aea698 | 2004-10-26 09:35:25 +0000 | [diff] [blame] | 680 | #ifdef NAN |
| 681 | check_xer(0, NAN); /* "<NOT-A-NUMBER/>" */ |
| 682 | #else |
Lev Walkin | 5f56091 | 2004-10-21 13:37:57 +0000 | [diff] [blame] | 683 | check_xer(0, zero/zero); /* "<NOT-A-NUMBER/>" */ |
Lev Walkin | 1aea698 | 2004-10-26 09:35:25 +0000 | [diff] [blame] | 684 | #endif |
| 685 | #ifdef INFINITY |
| 686 | check_xer(0, INFINITY); /* "<PLUS-INFINITY/>" */ |
| 687 | check_xer(0, -INFINITY); /* "<MINUS-INFINITY/>" */ |
| 688 | #else |
Lev Walkin | 5f56091 | 2004-10-21 13:37:57 +0000 | [diff] [blame] | 689 | check_xer(0, 1.0/zero); /* "<PLUS-INFINITY/>" */ |
| 690 | check_xer(0, -1.0/zero); /* "<MINUS-INFINITY/>" */ |
Lev Walkin | 1aea698 | 2004-10-26 09:35:25 +0000 | [diff] [blame] | 691 | #endif |
Lev Walkin | 5f56091 | 2004-10-21 13:37:57 +0000 | [diff] [blame] | 692 | check_xer(0, 1.0); |
| 693 | check_xer(0, -1.0); |
| 694 | check_xer(0, 1.5); |
| 695 | check_xer(0, 123); |
| 696 | check_xer(1, 0.0000000000000000000001); |
| 697 | check_xer(1, -0.0000000000000000000001); |
| 698 | |
Lev Walkin | 41ba1f2 | 2004-09-14 12:46:35 +0000 | [diff] [blame] | 699 | return 0; |
| 700 | } |