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");