infinity handling

diff --git a/skeletons/REAL.c b/skeletons/REAL.c
index 2373dde..6ce124e 100644
--- a/skeletons/REAL.c
+++ b/skeletons/REAL.c
@@ -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 @@
 	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 @@
 
 		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 @@
 			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 @@
 			}
 			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;
 	}
diff --git a/skeletons/tests/check-REAL.c b/skeletons/tests/check-REAL.c
index e61a54a..89ab326 100644
--- a/skeletons/tests/check-REAL.c
+++ b/skeletons/tests/check-REAL.c
@@ -143,13 +143,15 @@
 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");