Skip to content

Commit

Permalink
Implement abs_compare() and add equal_with_nan_inf()
Browse files Browse the repository at this point in the history
Tests now pass
  • Loading branch information
mikebentley15 committed Feb 26, 2020
1 parent 77808c6 commit 95d17c9
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 22 deletions.
27 changes: 26 additions & 1 deletion src/flit/flitHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
#include <algorithm>
#include <fstream>
#include <iostream>
#include <limits>
#include <mutex>
#include <ostream>
#include <random>
Expand All @@ -102,6 +103,7 @@
#include <vector>

#include <cfloat>
#include <cmath>

#ifndef FLIT_UNUSED
#define FLIT_UNUSED(x) (void)x
Expand Down Expand Up @@ -254,6 +256,24 @@ as_int(long double val) {
return temp & (~zero >> 48);
}

template <typename T>
bool equal_with_nan_inf(T a, T b) {
if (std::fpclassify(a) == std::fpclassify(b)) {
switch (std::fpclassify(a)) {
case FP_INFINITE:
case FP_NAN:
return std::signbit(a) == std::signbit(b);

case FP_NORMAL:
case FP_SUBNORMAL:
case FP_ZERO:
default:
return a == b;
}
}
return false;
}

/**
* Default comparison used by FLiT. Similar to
*
Expand All @@ -266,7 +286,12 @@ as_int(long double val) {
*/
template <typename T>
T abs_compare(T expected, T actual) {
// TODO: implement all other cases
if (equal_with_nan_inf(expected, actual)) {
return T(0.0);
}
if (std::isnan(expected) && std::isinf(actual)) {
return std::numeric_limits<T>::infinity();
}
return std::abs(actual - expected);
}

Expand Down
24 changes: 3 additions & 21 deletions tests/flit_src/tst_flitHelpers_h.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,32 +280,14 @@ TH_TEST(tst_as_int_128bit) {

namespace tst_abs_compare {

template <typename T>
bool equal_with_nan_inf(T a, T b) {
if (std::fpclassify(a) == std::fpclassify(b)) {
switch (std::fpclassify(a)) {
case FP_INFINITE:
case FP_NAN:
return std::signbit(a) == std::signbit(b);

case FP_NORMAL:
case FP_SUBNORMAL:
case FP_ZERO:
default:
return a == b;
}
}
return false;
}

template <typename T>
void tst_equal_with_nan_inf_impl() {
using lim = std::numeric_limits<T>;

static_assert(lim::has_quiet_NaN);
static_assert(lim::has_infinity);

auto eq = equal_with_nan_inf<T>;
auto &eq = flit::equal_with_nan_inf<T>;
T my_nan = lim::quiet_NaN();
T my_inf = lim::infinity();
T normal = -3.2;
Expand Down Expand Up @@ -370,8 +352,8 @@ void tst_abs_compare_impl() {
T normal = -3.2;
T zero = 0.0;

auto eq = equal_with_nan_inf<T>;
auto comp = flit::abs_compare<T>;
auto &eq = flit::equal_with_nan_inf<T>;
auto &comp = flit::abs_compare<T>;

// we have 25 cases
TH_VERIFY(eq(comp( my_nan, my_nan), zero ));
Expand Down

0 comments on commit 95d17c9

Please sign in to comment.