conversions between float and int are done working and tested; a few other clean ups
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;
          }