Skip to content

Commit

Permalink
Implement copysign
Browse files Browse the repository at this point in the history
  • Loading branch information
Rinzii committed Mar 13, 2024
1 parent 840a6b1 commit 33a63d1
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 0 deletions.
29 changes: 29 additions & 0 deletions include/ccmath/detail/fmanip/copysign.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,36 @@

#pragma once

#include "ccmath/internal/helpers/bits.hpp"
#include "ccmath/detail/compare/signbit.hpp"
#include "ccmath/detail/compare/isnan.hpp"
#include "ccmath/detail/basic/abs.hpp"

namespace ccm
{
namespace
{
namespace impl
{
template <typename T>
inline constexpr T copysign_impl(T x, T y)
{
if (ccm::isnan(x) || ccm::isnan(y))
{
if (ccm::signbit(y)) { return -std::numeric_limits<T>::quiet_NaN(); }
else { return std::numeric_limits<T>::quiet_NaN(); }
}

int sign_bit = ccm::signbit(y) ? -1 : 1;
return ccm::abs(x) * sign_bit;
}
} // namespace impl
} // namespace

template <typename T>
inline constexpr T copysign(T x, T y)
{
return impl::copysign_impl(x, y);
}

} // namespace ccm
11 changes: 11 additions & 0 deletions test/fmanip/copysign_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,17 @@

TEST(CcmathFmanipTests, Copysign)
{
EXPECT_EQ(ccm::copysign(1.0, +2.0), std::copysign(1.0, +2.0));
EXPECT_EQ(ccm::copysign(1.0, -2.0), std::copysign(1.0, -2.0));
EXPECT_EQ(ccm::copysign(std::numeric_limits<double>::infinity(), -2.0), std::copysign(std::numeric_limits<double>::infinity(), -2.0));

bool isCcmCopysignNan = std::isnan(ccm::copysign(std::numeric_limits<double>::quiet_NaN(), -2.0));
bool isStdCopysignNan = std::isnan(std::copysign(std::numeric_limits<double>::quiet_NaN(), -2.0));
bool isCcmCopysignNanNegative = std::signbit(ccm::copysign(std::numeric_limits<double>::quiet_NaN(), -2.0));
bool isStdCopysignNanNegative = std::signbit(std::copysign(std::numeric_limits<double>::quiet_NaN(), -2.0));
EXPECT_EQ(isCcmCopysignNan, isStdCopysignNan);
EXPECT_EQ(isCcmCopysignNanNegative, isStdCopysignNanNegative);

// TODO: Add more tests
}

0 comments on commit 33a63d1

Please sign in to comment.