Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write a portable constexpr std::copysign()?

In particular, it must work with NaNs as std::copysign does. Similarly, I need a constexpr std::signbit.

constexpr double copysign(double mag, double sgn)
{
    // how?
}

constexpr bool signbit(double arg)
{
    // how?
}

// produce the two types of NaNs
constexpr double nan_pos = copysign(std::numeric_limits<double>::quiet_NaN(), +1);
constexpr double nan_neg = copysign(std::numeric_limits<double>::quiet_NaN(), -1);

// must pass the checks
static_assert(signbit(nan_pos) == false);
static_assert(signbit(nan_neg) == true);

The story behind is that I need two types of NaNs at compile time, as well as ways to distinguish between them. The most straightforward way I can think of is to manipulate the sign bit of the NaNs. It does work at run time; now I just want to move some computations to compile time, and this is the last hurdle.

Notes: at the moment, I'm relying on GCC, as it has built-in versions of these functions and they are indeed constexpr, which is nice. But I want my codebase to compile on Clang and perhaps other compilers too.

like image 414
Hank Avatar asked Sep 20 '21 19:09

Hank


1 Answers

P0533: constexpr for <cmath> and <cstdlib> is now accepted.

Starting in C++23 you can just use std::copysign and std::syncbit.

like image 197
Alex Guteniev Avatar answered Sep 28 '22 07:09

Alex Guteniev