Skip to content

Commit

Permalink
modf now supports raw and pedantic
Browse files Browse the repository at this point in the history
  • Loading branch information
jtlap authored May 22, 2024
1 parent 115f1b6 commit b748c7d
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 14 deletions.
31 changes: 21 additions & 10 deletions include/eve/module/core/regular/modf.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@
#include <eve/module/core/constant/zero.hpp>
#include <eve/module/core/regular/zip.hpp>
#include <eve/arch/platform.hpp>
#include <iostream>

namespace eve
{
template<typename Options>
struct modf_t : elementwise_callable<modf_t, Options, pedantic_option>
struct modf_t : elementwise_callable<modf_t, Options, pedantic_option, raw_option, almost_option>
{
template<eve::value T>
EVE_FORCEINLINE constexpr zipped<T,T> operator()(T a) const noexcept
Expand Down Expand Up @@ -63,20 +64,28 @@ namespace eve
//! fractional and integral parts of `x`, each having the type and sign of `x`.
//!
//! In particular:
//! * If `x` is infinite `{Nan, x}` is returned.
//! * If `x` is infinite `{Nan, x}` is returned. (this is not standard conformant: see pedantic)
//! * If `x` is a `Nan` `{Nan, Nan}` is returned.
//!
//!
//! @groupheader{Example}
//!
//! @godbolt{doc/core/modf.cpp}
//!
//! @groupheader{Semantic Modifiers}
//!
//! * eve::raw
//!
//! The call `modf[raw](x)` does care about limits nor zero sign.
//!
//! * eve::pedantic
//!
//! The call `pedantic(modf)(x)` ensures standard conformity : if `x` is infinite,
//! The call `modf[pedantic](x)` ensures standard conformity : if `x` is infinite,
//! `{0, x}` is returned.
//!
//! * eve::almost
//!
//! The call `modf[almost [= tol}](x)` use `trunc[almost [= tol}](x)` to compute the integral part

//! @}
//================================================================================================

Expand All @@ -85,19 +94,21 @@ inline constexpr auto modf = functor<modf_t>;
namespace detail
{
template<typename T, callable_options O>
EVE_FORCEINLINE constexpr auto modf_(EVE_REQUIRES(cpu_), O const&, T a) noexcept
EVE_FORCEINLINE constexpr auto modf_(EVE_REQUIRES(cpu_), O const& o, T a) noexcept
{
if constexpr(floating_value<T>)
{
auto t = trunc(a);
if constexpr(O::contains(pedantic2) && platform::supports_infinites)
auto t = trunc[o.drop(pedantic2)](a);
if constexpr(O::contains(raw2))
{
auto f = if_else(is_infinite(a), eve::zero, a - t);
return eve::zip(f, t);
return eve::zip(a-t, t);
}
else
{
return eve::zip(a - t, t);
auto f = if_else(is_eqz(a), a, a-t);
if constexpr(O::contains(pedantic2) && platform::supports_infinites)
f = if_else(is_infinite(a), eve::zero, f);
return eve::zip(f, t);
}
}
else return eve::zip(zero(eve::as(a)), a);
Expand Down
21 changes: 17 additions & 4 deletions test/doc/core/modf.cpp
Original file line number Diff line number Diff line change
@@ -1,26 +1,39 @@
#include <eve/module/core.hpp>
#include <eve/wide.hpp>
#include <iostream>
#include <iomanip>

using wide_ft = eve::wide<float, eve::fixed<8>>;

int main()
{
wide_ft pf = {-0.0, 1.30f, -1.3f, eve::inf(eve::as<float>()), 0.0f,
eve::nan(eve::as<float>()), 0.678f, -0.678f};
eve::nan(eve::as<float>()), 2.0f, eve::prev(2.0f)};

auto [m, e] = eve::modf(pf);
auto [mp, ep] = eve::modf[eve::pedantic](pf);
std::cout << "---- simd" << '\n'
auto [mr, er] = eve::modf[eve::raw](pf);
auto [ma, ea] = eve::modf[eve::almost = 4](pf);
std::cout << "---- simd" << std::setprecision(8) << '\n'
<< "<- pf = " << pf << '\n'
<< "-> modf(pf) = [" << '\n'
<< " " << m << ", \n"
<< " " << e << '\n'
<< " ]\n"
<< "-> pedantic(modf)(pf) = [" << '\n'
<< "-> modf[pedantic](pf) = [" << '\n'
<< " " << mp << ", \n"
<< " " << ep << '\n'
<< " ]\n";
<< " ]\n"
<< "-> modf[raw](pf) = [" << '\n'
<< " " << mr << ", \n"
<< " " << er << '\n'
<< " ]\n"
<< "-> modf[almost = 4](pf) = [" << '\n'
<< " " << ma << ", \n"
<< " " << ea << '\n'
<< " ]\n"

;

float xf = 2.3;
auto [sm, se] = eve::modf(xf);
Expand Down
20 changes: 20 additions & 0 deletions test/unit/module/core/modf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,23 @@ TTS_CASE_TPL("Check behavior of modf on integer types full range", eve::test::si
TTS_EQUAL(p1, T(-16));
}
};

TTS_CASE_WITH("Check behavior of eve::modf(eve::wide)",
eve::test::simd::ieee_reals,
tts::generate(tts::randoms(0.999999, 1.0))
)
<typename T>(T const& a0)
{
auto [f, t] = eve::modf(a0);
auto [fp, tp] = eve::modf[eve::pedantic2](a0);
auto [fr, tr] = eve::modf[eve::raw2](a0);
auto [fa, ta] = eve::modf[eve::almost = 10](a0);
TTS_IEEE_EQUAL(f, eve::frac(a0));
TTS_IEEE_EQUAL(t, eve::trunc(a0));
TTS_IEEE_EQUAL(fp, eve::frac[eve::pedantic2](a0));
TTS_IEEE_EQUAL(tp, eve::trunc(a0));
TTS_IEEE_EQUAL(fr, eve::frac[eve::raw2](a0));
TTS_IEEE_EQUAL(tr, eve::trunc[eve::raw2](a0));
TTS_IEEE_EQUAL(fa, eve::frac[eve::almost = 10](a0));
TTS_IEEE_EQUAL(ta, eve::trunc[eve::almost = 10](a0));
};

0 comments on commit b748c7d

Please sign in to comment.