Added a nan/inf checker to the fp traits

This commit is contained in:
Paul Fd 2020-04-07 20:23:13 +02:00
parent 8b711780d7
commit 9613c0ed57
3 changed files with 53 additions and 0 deletions

View file

@ -188,6 +188,8 @@ void ADSREnvelope<Type>::getBlock(absl::Span<Type> output) noexcept
this->currentValue = currentValue; this->currentValue = currentValue;
this->shouldRelease = shouldRelease; this->shouldRelease = shouldRelease;
this->releaseDelay = releaseDelay; this->releaseDelay = releaseDelay;
ASSERT(!hasNanInf(output));
} }
template <class Type> template <class Type>

View file

@ -11,6 +11,7 @@
#pragma once #pragma once
#include "Config.h" #include "Config.h"
#include "Macros.h" #include "Macros.h"
#include "absl/types/span.h"
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
#include <random> #include <random>
@ -292,3 +293,36 @@ inline F fp_from_parts(bool sgn, int ex, uint64_t mant)
(static_cast<I>(sgn) << (T::e_bits + T::m_bits)); (static_cast<I>(sgn) << (T::e_bits + T::m_bits));
return u.real; return u.real;
} }
template<class F>
inline bool fp_naninf(F x)
{
typedef FP_traits<F> T;
typedef typename T::same_size_int I;
union { F real; I integer; } u;
u.real = x;
const auto all_ones = ((1u << T::e_bits) - 1);
const auto ex = (u.integer >> T::m_bits) & all_ones;
return ex == all_ones;
}
template<class Type>
bool hasNanInf(absl::Span<Type> span)
{
for (const auto& x: span)
if (fp_naninf(x))
return true;
return false;
}
template<class Type>
bool isValidAudio(absl::Span<Type> span)
{
for (const auto& x: span)
if (x < -1.0f || x > 1.0f)
return false;
return true;
}

View file

@ -7,6 +7,7 @@
#include "catch2/catch.hpp" #include "catch2/catch.hpp"
#include "sfizz/MathHelpers.h" #include "sfizz/MathHelpers.h"
#include <cmath> #include <cmath>
#include <limits>
TEST_CASE("[FloatMath] Fast ilog2 (float)") TEST_CASE("[FloatMath] Fast ilog2 (float)")
{ {
@ -51,3 +52,19 @@ TEST_CASE("[FloatMath] Break apart and reconstruct (double)")
REQUIRE(fp_from_parts<double>(sgn, ex, mant.num) == f); REQUIRE(fp_from_parts<double>(sgn, ex, mant.num) == f);
} }
} }
TEST_CASE("[FloatMath] Nan/Inf checker")
{
REQUIRE(fp_naninf(std::numeric_limits<double>::quiet_NaN()));
REQUIRE(fp_naninf(std::numeric_limits<float>::quiet_NaN()));
REQUIRE(fp_naninf(std::numeric_limits<double>::infinity()));
REQUIRE(fp_naninf(std::numeric_limits<float>::infinity()));
REQUIRE(fp_naninf(-std::numeric_limits<double>::infinity()));
REQUIRE(fp_naninf(-std::numeric_limits<float>::infinity()));
REQUIRE(!fp_naninf(0.0f));
REQUIRE(!fp_naninf(0.0));
REQUIRE(!fp_naninf(1.0f));
REQUIRE(!fp_naninf(1.0));
REQUIRE(!fp_naninf(-1.0f));
REQUIRE(!fp_naninf(-1.0));
}