From 1bbcf1cc397a6c40d5930e5d151c69195b202478 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sun, 22 Feb 2015 19:11:39 -0500 Subject: [PATCH] move complex to its own header --- toolbox/complex.h | 139 ++++++++++++++++++++++++++++++++++++++++++++++ toolbox/sane.cpp | 121 ++-------------------------------------- 2 files changed, 145 insertions(+), 115 deletions(-) create mode 100644 toolbox/complex.h diff --git a/toolbox/complex.h b/toolbox/complex.h new file mode 100644 index 0000000..28acc1a --- /dev/null +++ b/toolbox/complex.h @@ -0,0 +1,139 @@ +#ifndef __complex_h__ +#define __complex_h__ + +#include +#include + + // comp is an int64_t but 0x8000_0000_0000_0000 is NaN + //typedef int64_t complex; + +struct complex { + + public: + const uint64_t NaN = 0x8000000000000000; + + complex(const complex &rhs) = default; + + complex(uint64_t rhs) : _data(rhs) + {} + + template + complex(T t) + { + *this = t; + } + + bool isnan() const + { + return _data == NaN; + } + + complex &operator=(const complex &rhs) = default; + + complex &operator=(uint64_t rhs) + { + _data = rhs; + return *this; + } + + template + complex &operator=(T ld) + { + switch(std::fpclassify(ld)) + { + case FP_NAN: + _data = NaN; + break; + case FP_INFINITE: + if (std::signbit(ld)) + { + _data = -INT64_MAX; + } + else + { + _data = INT64_MAX; + } + break; + default: + _data = ld; + break; + } + + return *this; + } + + + operator uint64_t() const { + return _data; + } + + operator int64_t() const { + return _data; + } + + operator long double() const { + if (_data == NaN) + return NAN; + return _data; + } + + operator double() const { + if (_data == NaN) + return NAN; + return _data; + } + + operator float() const { + if (_data == NaN) + return NAN; + return _data; + } + + + private: + int64_t _data = 0; + + }; + +namespace its_complicated { + + + std::string to_string(complex c) + { + if (c.isnan()) return std::string("nan"); + + return std::to_string((int64_t)c); + } + + inline int fpclassify(complex c) { + if (c.isnan()) return FP_NAN; + if ((uint64_t)c == (uint64_t)0) return FP_ZERO; + return FP_NORMAL; + } + + inline int signbit(complex c) { + if (c.isnan()) return 0; + return ((int64_t)c < (int64_t)0) ? 1 : 0; + } + + inline int isnan(complex c) { + return c.isnan(); + } + + inline int isinf(complex c) { + return false; + } + + inline int isfinite(complex c) { + if (c.isnan()) return false; + return true; + } + + inline int isnormal(complex c) { + if (c.isnan()) return false; + if ((uint64_t)c == 0) return false; + return true; + } +} + +#endif diff --git a/toolbox/sane.cpp b/toolbox/sane.cpp index aa583fe..e6f9820 100644 --- a/toolbox/sane.cpp +++ b/toolbox/sane.cpp @@ -38,6 +38,7 @@ #include #include "stackframe.h" +#include "complex.h" using ToolBox::Log; @@ -46,7 +47,12 @@ namespace SANE { using std::to_string; +using std::fpclassify; +using std::signbit; +using its_complicated::to_string; +using its_complicated::fpclassify; +using its_complicated::signbit; namespace { // default environment is: @@ -103,121 +109,6 @@ using std::to_string; // long double is an 80-bit extended with an extra 48-bits of 0 padding. typedef long double extended; - // comp is an int64_t but 0x8000_0000_0000_0000 is NaN - //typedef int64_t complex; - - struct complex { - - public: - const uint64_t NaN = 0x8000000000000000; - complex(const complex &rhs) : _data(rhs._data) - {} - complex(uint64_t rhs) : _data(rhs) - {} - - bool isnan() const - { - return _data == NaN; - } - - complex &operator=(const complex &rhs) - { - _data = rhs._data; - return *this; - } - - complex &operator=(uint64_t rhs) - { - _data = rhs; - return *this; - } - - complex &operator=(long double ld) - { - switch(std::fpclassify(ld)) - { - case FP_NAN: - _data = NaN; - break; - case FP_INFINITE: - if (std::signbit(ld)) - { - _data = -INT64_MAX; - } - else - { - _data = INT64_MAX; - } - break; - default: - _data = ld; - break; - } - - return *this; - } - - - complex &operator=(double d) - { - switch(std::fpclassify(d)) - { - case FP_NAN: - _data = NaN; - break; - case FP_INFINITE: - if (std::signbit(d)) - { - _data = -INT64_MAX; - } - else - { - _data = INT64_MAX; - } - break; - default: - _data = d; - break; - } - - return *this; - } - - - operator uint64_t() const { - return _data; - } - - operator int64_t() const { - return _data; - } - - operator long double() const { - if (_data == NaN) - return NAN; - return _data; - } - - operator double() const { - if (_data == NaN) - return NAN; - return _data; - } - - - private: - int64_t _data; - - }; - - // can't override std::to_string, but can import std::to_string - // then override SANE::to_string. - std::string to_string(complex c) - { - if (c.isnan()) return std::string("nan"); - - return std::to_string((int64_t)c); - } template