Add support for quiet and signaling NaNs to the ieee header.
Fixes #127.
diff --git a/Changelog b/Changelog
index b5ca3e8..a3add38 100644
--- a/Changelog
+++ b/Changelog
@@ -1,3 +1,6 @@
+2020-02-16:
+ Add support for quiet and signaling NaNs to ieee header.
+
2019-10-31:
Add support for xtensa architecture.
Add support for nios2 architecture.
diff --git a/double-conversion/ieee.h b/double-conversion/ieee.h
index 8c3b862..3c2a597 100644
--- a/double-conversion/ieee.h
+++ b/double-conversion/ieee.h
@@ -45,6 +45,7 @@
static const uint64_t kExponentMask = DOUBLE_CONVERSION_UINT64_2PART_C(0x7FF00000, 00000000);
static const uint64_t kSignificandMask = DOUBLE_CONVERSION_UINT64_2PART_C(0x000FFFFF, FFFFFFFF);
static const uint64_t kHiddenBit = DOUBLE_CONVERSION_UINT64_2PART_C(0x00100000, 00000000);
+ static const uint64_t kQuietNanBit = DOUBLE_CONVERSION_UINT64_2PART_C(0x00080000, 00000000);
static const int kPhysicalSignificandSize = 52; // Excludes the hidden bit.
static const int kSignificandSize = 53;
static const int kExponentBias = 0x3FF + kPhysicalSignificandSize;
@@ -148,6 +149,15 @@
((d64 & kSignificandMask) != 0);
}
+ bool IsQuietNan() const {
+ return IsNan() && ((AsUint64() & kQuietNanBit) != 0);
+ }
+
+ bool IsSignalingNan() const {
+ return IsNan() && ((AsUint64() & kQuietNanBit) == 0);
+ }
+
+
bool IsInfinite() const {
uint64_t d64 = AsUint64();
return ((d64 & kExponentMask) == kExponentMask) &&
@@ -266,6 +276,7 @@
static const uint32_t kExponentMask = 0x7F800000;
static const uint32_t kSignificandMask = 0x007FFFFF;
static const uint32_t kHiddenBit = 0x00800000;
+ static const uint32_t kQuietNanBit = 0x00400000;
static const int kPhysicalSignificandSize = 23; // Excludes the hidden bit.
static const int kSignificandSize = 24;
@@ -324,6 +335,15 @@
((d32 & kSignificandMask) != 0);
}
+ bool IsQuietNan() const {
+ return IsNan() && ((AsUint32() & kQuietNanBit) != 0);
+ }
+
+ bool IsSignalingNan() const {
+ return IsNan() && ((AsUint32() & kQuietNanBit) == 0);
+ }
+
+
bool IsInfinite() const {
uint32_t d32 = AsUint32();
return ((d32 & kExponentMask) == kExponentMask) &&
diff --git a/test/cctest/test-ieee.cc b/test/cctest/test-ieee.cc
index aebecf5..312eccd 100644
--- a/test/cctest/test-ieee.cc
+++ b/test/cctest/test-ieee.cc
@@ -26,6 +26,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stdlib.h>
+#include <limits>
#include "cctest.h"
#include "double-conversion/diy-fp.h"
@@ -444,3 +445,19 @@
CHECK_EQ(-Double::Infinity(),
Double(DOUBLE_CONVERSION_UINT64_2PART_C(0xffefffff, ffffffff)).PreviousDouble());
}
+
+TEST(SignalingNan) {
+ Double nan(Double::NaN());
+ CHECK(nan.IsNan());
+ CHECK(nan.IsQuietNan());
+ CHECK(Double(std::numeric_limits<double>::quiet_NaN()).IsQuietNan());
+ CHECK(Double(std::numeric_limits<double>::signaling_NaN()).IsSignalingNan());
+}
+
+TEST(SignalingNanSingle) {
+ Single nan(Single::NaN());
+ CHECK(nan.IsNan());
+ CHECK(nan.IsQuietNan());
+ CHECK(Single(std::numeric_limits<float>::quiet_NaN()).IsQuietNan());
+ CHECK(Single(std::numeric_limits<float>::signaling_NaN()).IsSignalingNan());
+}