diff --git a/skeletons/REAL.c b/skeletons/REAL.c index 927a94b36b83a7db8a78a41b8ed3e336814ec3ce..2373dde9bc24bd2280e0f01c74f1edb2d4df526e 100644 --- a/skeletons/REAL.c +++ b/skeletons/REAL.c @@ -17,8 +17,8 @@ #endif #ifndef NAN -static const double nan0; -#define NAN (nan0/nan0) +static const double real_nan0; +#define NAN (real_nan0/real_nan0) #endif /* @@ -60,13 +60,17 @@ REAL__dump(double d, int canonical, asn_app_consume_bytes_f *cb, void *app_key) /* * ilogb(+-0) returns -INT_MAX or INT_MIN (platform-dependent) * ilogb(+-inf) returns INT_MAX + * ilogb(NaN) returns INT_MIN or INT_MAX (platform-dependent) */ expval = ilogb(d); - if(expval <= -INT_MAX /* Also catches (d == 0) */ - || expval == INT_MAX /* catches finite() which catches isnan() */ + if(expval <= -INT_MAX /* Also catches +-0 and maybe isnan() */ + || expval == INT_MAX /* catches isfin() and maybe isnan() */ ) { /* fpclassify(3) is not portable yet */ - if(expval <= -INT_MAX) { + if(isnan(d)) { + buf = "<NOT-A-NUMBER/>"; + buflen = 15; + } else if(expval <= -INT_MAX) { if(copysign(1.0, d) < 0.0) { buf = "-0"; buflen = 2; @@ -74,7 +78,7 @@ REAL__dump(double d, int canonical, asn_app_consume_bytes_f *cb, void *app_key) buf = "0"; buflen = 1; } - } else if(isinf(d)) { + } else { /* isinf() */ if(copysign(1.0, d) < 0.0) { buf = "<MINUS-INFINITY/>"; buflen = 17; @@ -82,9 +86,6 @@ REAL__dump(double d, int canonical, asn_app_consume_bytes_f *cb, void *app_key) buf = "<PLUS-INFINITY/>"; buflen = 16; } - } else { - buf = "<NOT-A-NUMBER/>"; - buflen = 15; } return (cb(buf, buflen, app_key) < 0) ? -1 : buflen; } @@ -271,7 +272,7 @@ asn1_REAL2double(const REAL_t *st, double *dbl_value) { *dbl_value = NAN; return 0; case 0x43: /* 01000011: minus zero */ - *dbl_value = NAN; + *dbl_value = -0.0; return 0; } @@ -412,11 +413,11 @@ asn1_double2REAL(REAL_t *st, double dbl_value) { /* * ilogb(+-0) returns -INT_MAX or INT_MIN (platform-dependent) * ilogb(+-inf) returns INT_MAX + * ilogb(NaN) returns INT_MIN or INT_MAX (platform-dependent) */ expval = ilogb(dbl_value); - - if(expval <= -INT_MAX /* Also catches (dbl_value == 0) */ - || expval == INT_MAX /* catches finite() which catches isnan() */ + if(expval <= -INT_MAX /* Also catches +-0 and maybe isnan() */ + || expval == INT_MAX /* catches isfin() and maybe isnan() */ ) { if(!st->buf || st->size < 2) { ptr = (uint8_t *)MALLOC(2); @@ -424,7 +425,11 @@ asn1_double2REAL(REAL_t *st, double dbl_value) { st->buf = ptr; } /* fpclassify(3) is not portable yet */ - if(expval <= -INT_MAX) { + if(isnan(dbl_value)) { + st->buf[0] = 0x42; /* NaN */ + st->buf[1] = 0; + st->size = 1; + } else if(expval <= -INT_MAX) { if(copysign(1.0, dbl_value) < 0.0) { st->buf[0] = 0x80 | 0x40; st->buf[1] = 0; @@ -433,7 +438,7 @@ asn1_double2REAL(REAL_t *st, double dbl_value) { st->buf[0] = 0; /* JIC */ st->size = 0; } - } else if(isinf(dbl_value)) { + } else { /* isinf() */ if(copysign(1.0, dbl_value) < 0.0) { st->buf[0] = 0x41; /* MINUS-INFINITY */ } else { @@ -441,10 +446,6 @@ asn1_double2REAL(REAL_t *st, double dbl_value) { } st->buf[1] = 0; st->size = 1; - } else { - st->buf[0] = 0x42; /* NaN */ - st->buf[1] = 0; - st->size = 1; } return 0; } diff --git a/skeletons/tests/check-REAL.c b/skeletons/tests/check-REAL.c index 198113ceede3f3b024ec4dbea873b5292b6cc9f6..e61a54a05df10669fa49872730da34325c25f27c 100644 --- a/skeletons/tests/check-REAL.c +++ b/skeletons/tests/check-REAL.c @@ -75,7 +75,7 @@ check(REAL_t *rn, double orig_dbl, const char *sample, const char *canonical_sam printf("converted into ["); for(p = rn->buf, end = p + rn->size; p < end; p++) printf("%02x", *p); - printf("]\n"); + printf("]: %d\n", rn->size); ret = asn1_REAL2double(rn, &val); assert(ret == 0); @@ -86,8 +86,7 @@ check(REAL_t *rn, double orig_dbl, const char *sample, const char *canonical_sam printf("] (ilogb %d)\n", ilogb(val)); printf("%.12f vs %.12f\n", orig_dbl, val); - - assert(orig_dbl == val); + assert(orig_dbl == val || (isnan(orig_dbl) && isnan(val))); printf("OK\n"); check_str_repr(val, sample, canonical_sample); @@ -144,9 +143,11 @@ check_buf(uint8_t *buf, size_t bufsize, double verify, const char *sample, const int main() { REAL_t rn; + static const double c_NaN = 0.0; memset(&rn, 0, sizeof(rn)); + check(&rn, c_NaN/c_NaN, "<NOT-A-NUMBER/>", "<NOT-A-NUMBER/>"); check(&rn, 0.0, "0", "0"); check(&rn, -0.0, "-0", "-0"); /* minus-zero */ check(&rn, 1.0, "1.0", "1.0E0");