mirror of https://gerrit.osmocom.org/asn1c
infinity handling
git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@427 59561ff5-6e30-0410-9f3c-9617f08c8826
This commit is contained in:
parent
8f6ded0611
commit
b1f8d61021
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Reference in New Issue