infinity handling

git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@427 59561ff5-6e30-0410-9f3c-9617f08c8826
This commit is contained in:
vlm 2004-09-27 22:16:18 +00:00
parent 8f6ded0611
commit b1f8d61021
2 changed files with 40 additions and 50 deletions

View File

@ -12,13 +12,9 @@
#undef INT_MAX
#define INT_MAX ((int)(((unsigned int)-1) >> 1))
#ifndef INFINITY
#define INFINITY HUGE_VAL
#endif
#ifndef NAN
static const double real_nan0;
#define NAN (real_nan0/real_nan0)
static const double real_zero;
#define NAN (real_zero/real_zero)
#endif
/*
@ -52,40 +48,31 @@ REAL__dump(double d, int canonical, asn_app_consume_bytes_f *cb, void *app_key)
ssize_t buflen = sizeof(local_buf);
const char *fmt = canonical?"%.15E":"%.15f";
ssize_t ret;
int expval;
/*
* Check whether it is a special 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(d);
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(isnan(d)) {
buf = "<NOT-A-NUMBER/>";
buflen = 15;
} else if(expval <= -INT_MAX) {
if(copysign(1.0, d) < 0.0) {
buf = "-0";
buflen = 2;
} else {
buf = "0";
buflen = 1;
}
} else { /* isinf() */
if(copysign(1.0, d) < 0.0) {
buf = "<MINUS-INFINITY/>";
buflen = 17;
} else {
buf = "<PLUS-INFINITY/>";
buflen = 16;
}
/* fpclassify(3) is not portable yet */
if(isnan(d)) {
buf = "<NOT-A-NUMBER/>";
buflen = 15;
return (cb(buf, buflen, app_key) < 0) ? -1 : buflen;
} else if(isinf(d)) {
if(copysign(1.0, d) < 0.0) {
buf = "<MINUS-INFINITY/>";
buflen = 17;
} else {
buf = "<PLUS-INFINITY/>";
buflen = 16;
}
return (cb(buf, buflen, app_key) < 0) ? -1 : buflen;
} else if(ilogb(d) <= -INT_MAX) {
if(copysign(1.0, d) < 0.0) {
buf = "-0";
buflen = 2;
} else {
buf = "0";
buflen = 1;
}
return (cb(buf, buflen, app_key) < 0) ? -1 : buflen;
}
@ -259,10 +246,10 @@ asn1_REAL2double(const REAL_t *st, double *dbl_value) {
switch(st->buf[0]) {
case 0x40: /* 01000000: PLUS-INFINITY */
*dbl_value = INFINITY;
*dbl_value = 1.0/real_zero;
return 0;
case 0x41: /* 01000001: MINUS-INFINITY */
*dbl_value = -INFINITY;
*dbl_value = -1.0/real_zero;
return 0;
/*
* The following cases are defined by
@ -429,16 +416,7 @@ asn1_double2REAL(REAL_t *st, double 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;
st->size = 2;
} else {
st->buf[0] = 0; /* JIC */
st->size = 0;
}
} else { /* isinf() */
} else if(isinf(dbl_value)) {
if(copysign(1.0, dbl_value) < 0.0) {
st->buf[0] = 0x41; /* MINUS-INFINITY */
} else {
@ -446,6 +424,16 @@ asn1_double2REAL(REAL_t *st, double dbl_value) {
}
st->buf[1] = 0;
st->size = 1;
} else {
if(copysign(1.0, dbl_value) < 0.0) {
st->buf[0] = 0x80 | 0x40;
st->buf[1] = 0;
st->size = 2;
} else {
/* no content octets: positive zero */
st->buf[0] = 0; /* JIC */
st->size = 0;
}
}
return 0;
}

View File

@ -143,13 +143,15 @@ 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;
static const double zero = 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, zero/zero, "<NOT-A-NUMBER/>", "<NOT-A-NUMBER/>");
check(&rn, 1.0/zero, "<PLUS-INFINITY/>", "<PLUS-INFINITY/>");
check(&rn, -1.0/zero, "<MINUS-INFINITY/>", "<MINUS-INFINITY/>");
check(&rn, 1.0, "1.0", "1.0E0");
check(&rn, -1.0, "-1.0", "-1.0E0");
check(&rn, 1.5, "1.5", "1.5E0");