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