Skip to content

Commit

Permalink
WIP: control and serialization of exceptional values for efloat
Browse files Browse the repository at this point in the history
  • Loading branch information
Ravenwater committed Nov 1, 2024
1 parent 307ab83 commit 589a373
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 11 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 29 additions & 3 deletions elastic/efloat/api/api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ try {
std::cout << "significant : " << significant<double>(a) << '\n';
}

// default behavior
std::cout << "+--------- Default efloat has no subnormals\n";
// interacting with subnormals
std::cout << "+--------- efloat has no subnormals\n";
{
using TestType = efloat;

Expand Down Expand Up @@ -105,7 +105,33 @@ try {
}

// explicit configuration
std::cout << "+--------- Explicit configuration of a efloat\n";
std::cout << "+--------- exceptional values of an efloat\n";
{
using TestType = efloat;

TestType e;

double d;
d = std::numeric_limits<double>::infinity();
// std::cout << d << '\n';
e = d;
std::cout << "+infinity : " << e << '\n';
e = -d;
std::cout << "-infinity : " << e << '\n';

d = std::numeric_limits<double>::signaling_NaN();
// std::cout << d << " : " << '\n';
e = d;
std::cout << "signaling NaN : " << e << '\n';

d = std::numeric_limits<double>::quiet_NaN();
// std::cout << d << " : " << '\n';
e = d;
std::cout << "quiet NaN : " << e << '\n';
}

// explicit configuration
std::cout << "+--------- explicit configuration of a efloat\n";
{

}
Expand Down
40 changes: 32 additions & 8 deletions include/universal/number/efloat/efloat_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,11 @@ class efloat {
bool iseven() const noexcept { return !isodd(); }
bool ispos() const noexcept { return (_state == FloatingPointState::Normal && !_sign); }
bool isneg() const noexcept { return (_state == FloatingPointState::Normal && _sign); }
bool isinf() const noexcept { return (_state == FloatingPointState::Infinite); }
bool isnan() const noexcept { return (_state == FloatingPointState::QuietNaN || _state == FloatingPointState::SignalingNaN); }
bool isqnan() const noexcept { return (_state == FloatingPointState::QuietNaN); }
bool issnan() const noexcept { return (_state == FloatingPointState::SignalingNaN); }


// value information selectors
int sign() const noexcept { return (_sign ? -1 : 1); }
Expand Down Expand Up @@ -211,6 +216,7 @@ class efloat {
efloat& convert_ieee754(Real rhs) noexcept {
clear();
bool isSubnormal{ false };
int nan_type{ NAN_TYPE_NEITHER };
switch (std::fpclassify(rhs)) {
case FP_ZERO:
_state = FloatingPointState::Zero;
Expand All @@ -220,13 +226,20 @@ class efloat {
return *this;
case FP_NAN:
_sign = sw::universal::sign(rhs);
_state = (_sign ? FloatingPointState::SignalingNaN : FloatingPointState::QuietNaN);
// x86 specific: the top bit of the significand = 1 for quiet, 0 for signaling
checkNaN(rhs, nan_type);
if (nan_type == NAN_TYPE_QUIET) {
_state = FloatingPointState::QuietNaN;
}
else {
_state = FloatingPointState::SignalingNaN;
}
_exponent = 0;
// stay limbless
return *this;
case FP_INFINITE:
_state = FloatingPointState::Infinite;
_sign = false;
_sign = sw::universal::sign(rhs);
_exponent = 0;
// stay limbless
return *this;
Expand Down Expand Up @@ -343,12 +356,23 @@ inline std::ostream& operator<<(std::ostream& ostr, const efloat& rhs) {
// we need to transform the efloat into a string
std::stringstream ss;

std::streamsize prec = ostr.precision();
std::streamsize width = ostr.width();
std::ios_base::fmtflags ff;
ff = ostr.flags();
ss.flags(ff);
ss << std::setw(width) << std::setprecision(prec) << "TBD";
if (rhs.isinf()) {
ss << (rhs.sign() == -1 ? "-inf" : "+inf");
}
else if (rhs.isqnan()) {
ss << "nan(qnan)";
}
else if (rhs.issnan()) {
ss << "nan(snan)";
}
else {
std::streamsize prec = ostr.precision();
std::streamsize width = ostr.width();
std::ios_base::fmtflags ff;
ff = ostr.flags();
ss.flags(ff);
ss << std::setw(width) << std::setprecision(prec) << "TBD";
}

return ostr << ss.str();
}
Expand Down

0 comments on commit 589a373

Please sign in to comment.