conversions between float and int are done working and tested; a few other clean ups
diff --git a/README.md b/README.md
index abe2498..c3795dc 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
 
 **Implemented in C with minimal dependency** – The only dependencies
   are C99, <stdint.h>, <stddef.h>, <stdbool.h> and <string.h> making
-  it highly portable. <math.h> is used too, but its use can
+  it highly portable. <math.h> and <fenv.h> are used too, but their use can
   disabled. No #ifdefs or compiler options need to be set for QCBOR to
   run correctly.
 
diff --git a/inc/qcbor/qcbor_common.h b/inc/qcbor/qcbor_common.h
index 20dff0e..04d9d04 100644
--- a/inc/qcbor/qcbor_common.h
+++ b/inc/qcbor/qcbor_common.h
@@ -397,6 +397,12 @@
         to and from double and float types. */
    QCBOR_ERR_HW_FLOAT_DISABLED = 36,
 
+    /** Unable to complete operation because a floating-point value that
+     is a NaN (not a number), that is too large, too small,
+     infinity or -infinity was encountered in encoded CBOR. Usually
+     this because conversion of the float-point value was being attempted. */
+    QCBOR_ERR_FLOAT_EXCEPTION = 37,
+
    /* This is stored in uint8_t; never add values > 255 */
 } QCBORError;
 
diff --git a/inc/qcbor/qcbor_spiffy_decode.h b/inc/qcbor/qcbor_spiffy_decode.h
index 2f73770..afaad1b 100644
--- a/inc/qcbor/qcbor_spiffy_decode.h
+++ b/inc/qcbor/qcbor_spiffy_decode.h
@@ -1830,17 +1830,8 @@
                                          UsefulBufC         *pBstr);
 
 
-// Semi private
-void QCBORDecode_GetTaggedItemInMapN(QCBORDecodeContext *pMe,
-                                     int64_t             nLabel,
-                                     TagSpecification    TagSpec,
-                                     QCBORItem          *pItem);
 
-// Semi private
-void QCBORDecode_GetTaggedItemInMapSZ(QCBORDecodeContext *pMe,
-                                      const char *        szLabel,
-                                      TagSpecification    TagSpec,
-                                      QCBORItem          *pItem);
+
 
 // Semi private
 void QCBORDecode_GetTaggedStringInMapN(QCBORDecodeContext *pMe,
diff --git a/src/qcbor_decode.c b/src/qcbor_decode.c
index 6c66f1e..d9ab840 100644
--- a/src/qcbor_decode.c
+++ b/src/qcbor_decode.c
@@ -36,7 +36,8 @@
 #include "ieee754.h" // Does not use math.h
 
 #ifndef QCBOR_DISABLE_FLOAT_HW_USE
-#include <math.h> // For isnan(). TODO: list
+#include <math.h> // For isnan(), llround(), llroudf(), round(), roundf() TODO: list
+#include <fenv.h> // feclearexcept(), fetestexcept()
 #endif
 
 
@@ -2872,9 +2873,8 @@
 
 
 
-
-// Semi-private
-// TODO: inline or collapse with QCBORDecode_GetTaggedStringInMapN?
+// This could be semi-private if need be
+static inline
 void QCBORDecode_GetTaggedItemInMapN(QCBORDecodeContext *pMe,
                                      int64_t             nLabel,
                                      TagSpecification    TagSpec,
@@ -2888,7 +2888,9 @@
    pMe->uLastError = (uint8_t)CheckTagRequirement(TagSpec, pItem);
 }
 
-// Semi-private
+
+// This could be semi-private if need be
+static inline
 void QCBORDecode_GetTaggedItemInMapSZ(QCBORDecodeContext *pMe,
                                      const char          *szLabel,
                                      TagSpecification    TagSpec,
@@ -3962,8 +3964,6 @@
 
 
 
-#include "fenv.h"
-
 
 /*
 Convert a integers and floats to an int64_t.
@@ -3984,17 +3984,22 @@
       case QCBOR_TYPE_DOUBLE:
 #ifndef QCBOR_DISABLE_FLOAT_HW_USE
          if(uConvertTypes & QCBOR_CONVERT_TYPE_FLOAT) {
-            // TODO: what about under/overflow here?
-            // Invokes the floating-point HW and/or compiler-added libraries
-            feclearexcept(FE_ALL_EXCEPT);
+            /* https://pubs.opengroup.org/onlinepubs/009695399/functions/llround.html
+             http://www.cplusplus.com/reference/cmath/llround/
+             */
+            // Not interested in FE_INEXACT
+            feclearexcept(FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW|FE_DIVBYZERO);
             if(pItem->uDataType == QCBOR_TYPE_DOUBLE) {
                *pnValue = llround(pItem->val.dfnum);
             } else {
                *pnValue = lroundf(pItem->val.fnum);
             }
-            if(fetestexcept(FE_INVALID)) {
-               // TODO: better error code
-               return QCBOR_ERR_CONVERSION_UNDER_OVER_FLOW;
+            if(fetestexcept(FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW|FE_DIVBYZERO)) {
+               // llround() shouldn't result in divide by zero, but catch
+               // it here in case it unexpectedly does.  Don't try to
+               // distinguish between the various exceptions because it seems
+               // they vary by CPU, compiler and OS.
+               return QCBOR_ERR_FLOAT_EXCEPTION;
             }
          } else {
             return  QCBOR_ERR_UNEXPECTED_TYPE;
@@ -4296,21 +4301,47 @@
       case QCBOR_TYPE_FLOAT:
 #ifndef QCBOR_DISABLE_FLOAT_HW_USE
          if(uConvertTypes & QCBOR_CONVERT_TYPE_FLOAT) {
-            // TODO: this code needs work
-            feclearexcept(FE_ALL_EXCEPT);
-            double dRounded = round(pItem->val.dfnum);
-            // TODO: over/underflow
-            if(fetestexcept(FE_INVALID)) {
-               // TODO: better error code
-               return QCBOR_ERR_CONVERSION_UNDER_OVER_FLOW;
-            } else if(isnan(dRounded)) {
-               // TODO: better error code
-               return QCBOR_ERR_CONVERSION_UNDER_OVER_FLOW;
-            } else if(dRounded >= 0) {
-               *puValue = (uint64_t)dRounded;
+            // Can't use llround here because it will not convert values
+            // greater than INT64_MAX and less than UINT64_MAX that
+            // need to be converted so it is more complicated.
+            feclearexcept(FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW|FE_DIVBYZERO);
+            if(pItem->uDataType == QCBOR_TYPE_DOUBLE) {
+               if(isnan(pItem->val.dfnum)) {
+                  return QCBOR_ERR_FLOAT_EXCEPTION;
+               } else if(pItem->val.dfnum < 0) {
+                  return QCBOR_ERR_NUMBER_SIGN_CONVERSION;
+               } else {
+                  double dRounded = round(pItem->val.dfnum);
+                  // See discussion in DecodeDateEpoch() for
+                  // explanation of - 0x7ff
+                  if(dRounded > (double)(UINT64_MAX- 0x7ff)) {
+                     return QCBOR_ERR_CONVERSION_UNDER_OVER_FLOW;
+                  }
+                  *puValue = (uint64_t)dRounded;
+               }
             } else {
-               return QCBOR_ERR_NUMBER_SIGN_CONVERSION;
+               if(isnan(pItem->val.fnum)) {
+                  return QCBOR_ERR_FLOAT_EXCEPTION;
+               } else if(pItem->val.fnum < 0) {
+                  return QCBOR_ERR_NUMBER_SIGN_CONVERSION;
+               } else {
+                  float fRounded = roundf(pItem->val.fnum);
+                  // See discussion in DecodeDateEpoch() for
+                  // explanation of - 0x7ff
+                  if(fRounded > (float)(UINT64_MAX- 0x7ff)) {
+                     return QCBOR_ERR_CONVERSION_UNDER_OVER_FLOW;
+                  }
+                  *puValue = (uint64_t)fRounded;
+               }
             }
+            if(fetestexcept(FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW|FE_DIVBYZERO)) {
+               // round() and roundf() shouldn't result in exceptions here, but
+               // catch them to be robust and thorough. Don't try to
+               // distinguish between the various exceptions because it seems
+               // they vary by CPU, compiler and OS.
+               return QCBOR_ERR_FLOAT_EXCEPTION;
+            }
+
          } else {
             return QCBOR_ERR_UNEXPECTED_TYPE;
          }
@@ -4592,6 +4623,7 @@
 #ifndef QCBOR_DISABLE_FLOAT_HW_USE
          if(uConvertTypes & QCBOR_CONVERT_TYPE_FLOAT) {
             if(uConvertTypes & QCBOR_CONVERT_TYPE_FLOAT) {
+               // Simple cast does the job.
                *pdValue = (double)pItem->val.fnum;
             } else {
                return QCBOR_ERR_UNEXPECTED_TYPE;
@@ -4615,7 +4647,8 @@
       case QCBOR_TYPE_INT64:
 #ifndef QCBOR_DISABLE_FLOAT_HW_USE
          if(uConvertTypes & QCBOR_CONVERT_TYPE_XINT64) {
-            // TODO: how does this work?
+            // A simple cast seems to do the job with no worry of exceptions.
+            // There will be precision loss for some values.
             *pdValue = (double)pItem->val.int64;
 
          } else {
@@ -4629,7 +4662,9 @@
       case QCBOR_TYPE_UINT64:
 #ifndef QCBOR_DISABLE_FLOAT_HW_USE
          if(uConvertTypes & QCBOR_CONVERT_TYPE_XINT64) {
-             *pdValue = (double)pItem->val.uint64;
+            // A simple cast seems to do the job with no worry of exceptions.
+            // There will be precision loss for some values.
+            *pdValue = (double)pItem->val.uint64;
          } else {
             return QCBOR_ERR_UNEXPECTED_TYPE;
          }
diff --git a/test/qcbor_decode_tests.c b/test/qcbor_decode_tests.c
index a3798fe..3299567 100644
--- a/test/qcbor_decode_tests.c
+++ b/test/qcbor_decode_tests.c
@@ -5220,9 +5220,9 @@
       {(uint8_t[]){0xfa, 0x7f, 0xc0, 0x00, 0x00}, 5},
 #ifndef QCBOR_DISABLE_FLOAT_HW_USE
       0,
-      QCBOR_ERR_CONVERSION_UNDER_OVER_FLOW,
+      QCBOR_ERR_FLOAT_EXCEPTION,
       0,
-      QCBOR_ERR_CONVERSION_UNDER_OVER_FLOW,
+      QCBOR_ERR_FLOAT_EXCEPTION,
 #else /* QCBOR_DISABLE_FLOAT_HW_USE */
       0,
       QCBOR_ERR_HW_FLOAT_DISABLED,
@@ -5281,7 +5281,24 @@
       0.0,
       QCBOR_ERR_UNEXPECTED_TYPE
 #endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
-   }
+   },
+   {
+      "+inifinity",
+      {(uint8_t[]){0xfa, 0x7f, 0x80, 0x00, 0x00}, 5},
+#ifndef QCBOR_DISABLE_FLOAT_HW_USE
+      0,
+      QCBOR_ERR_FLOAT_EXCEPTION,
+      0,
+      QCBOR_ERR_CONVERSION_UNDER_OVER_FLOW,
+#else /* QCBOR_DISABLE_FLOAT_HW_USE */
+      0,
+      QCBOR_ERR_HW_FLOAT_DISABLED,
+      0,
+      QCBOR_ERR_HW_FLOAT_DISABLED,
+#endif /* QCBOR_DISABLE_FLOAT_HW_USE */
+      INFINITY,
+      QCBOR_SUCCESS
+   },
 };
 
 
@@ -5349,7 +5366,6 @@
                return (int32_t)(7000+nIndex);
             }
          } else {
-            // TODO: this comparison may need a margin of error
             if(pF->dConvertToDouble != d) {
                return (int32_t)(8000+nIndex);
             }