Constexpr Math Functions
Actually, because of old and annoying legacy, almost none of the math functions can be constexpr
, since they all have the side-effect of setting errno
on various error conditions, usually domain errors.
Why doesn't the C++ standard library provide constexpr versions of the cmath functions?
It hasn't been standardized yet. An initial proposal was submitted just last week, but only covering utility and linear operations and not any transcendental functions. Math is hard and floating-point math is complicated. For example, implementations don't allow overflows to infinity in constexpr
, but this isn't yet clearly standardized.
The compiler's constexpr
interpreter would have to special-case the math library interface, since unlike the rest of the standard library, it can't see its implementation.
GCC does offer constant evaluation of math functions as a nonconforming extension.
Getting constexpr to work with pow in C++17 on OSX
First, you can't initialize constexpr
class members with functions that aren't constexpr
and std::pow
isn't constepxr
in standard C++17 . The workaround is to declare them const
. While they can't be used in places that require a compile time const
they are immutable. A traditional approach is declaring them in header which you include as needed in source files. Then you hneed one implementation file that defines the static const members.
If your code requires compile time const's or constexpr your only option is to write your own pow
.
Here's one way to initialize const statics with functions that are not constexpr
prior to executing the main() using a portion of your question that shows the technique:
Create a header, constinit.h, that declares the class
// include header guards
// declare the static consts
struct ClassName {
static double DEFAULT_TARGET_TINITIAL_DIGITS_FROM_1; // represents 0.99
static double DEFAULT_TARGET_INITIAL_PBAD; // to be initialized by pow
};
Create an implementation file that initializes the statics:
#include "constinit.h"
#include <cmath>
double ClassName::DEFAULT_TARGET_TINITIAL_DIGITS_FROM_1{ 2 }; // represents 0.99
double ClassName::DEFAULT_TARGET_INITIAL_PBAD = (1 - std::pow(10, -DEFAULT_TARGET_TINITIAL_DIGITS_FROM_1));
To use the statics:
#include <iostream>
#include "constinit.h"
int main()
{
std::cout << ClassName::DEFAULT_TARGET_INITIAL_PBAD << std::endl;
}
If constexpr
for compile time initialization is required you need to define your own constexpr
pow function. This works in C++17:
#pragma once // or header guards per your preference
constexpr double my_pow(double x, int exp)
{
int sign = 1;
if (exp < 0)
{
sign = -1;
exp = -exp;
}
if (exp == 0)
return x < 0 ? -1.0 : 1.0;
double ret = x;
while (--exp)
ret *= x;
return sign > 0 ? ret : 1.0/ret;
}
class ClassName {
public:
static constexpr double DEFAULT_TARGET_TINITIAL_DIGITS_FROM_1 = 2; // represents 0.99
static constexpr double DEFAULT_TARGET_TFINAL_DIGITS_FROM_0 = 10; // represents 1e-10
static constexpr double DEFAULT_TARGET_INITIAL_PBAD = (1 - my_pow(10, -DEFAULT_TARGET_TINITIAL_DIGITS_FROM_1));
static constexpr double DEFAULT_TARGET_FINAL_PBAD = my_pow(10, -DEFAULT_TARGET_TFINAL_DIGITS_FROM_0);
static constexpr double DEFAULT_ERROR_TOL_DIGITS = 0.9; // as a fraction of digits in the last place from the above.
static constexpr double DEFAULT_SAMPLE_TIME = 1;
// more unrelated code
};
Is there a constexpr alternative to modf
Is there a constexpr alternative to modf
There is no standard constexpr alternative to modf or related math functions.
but the function is not constexpr. What is the reason for this
Those functions pre-exist constexpr. They even pre-exist C++. As such, when those founctions were specified, they couldn't have been constexpr.
There are no standard constexpr alternatives because such proposal hasn't been accepted into the standard. Such change has been proposed, so this may potentially change in a future standard: P1383
what is the alternative?
Wait for the potential future standard, or do the math without using standard functions.
Why aren't standard library common mathematical functions constant expressions?
I think the only reason is nobody wrote a proposal to make them constexpr. In general it is possible as they are pure functions. Implementations can use compiler intrinsics to implement them for theier lib, so no "real" implementation is needed. But without proposal you can not count on constexpr
implementations of these features.
In C++11 is sqrt defined as constexpr?
std::sqrt
is not defined as constexpr
, according to section 26.8 of N3291: the C++11 FDIS (and I doubt they added it to the final standard after that). One could possibly write such a version, but the standard library version is not constexpr
.
Related Topics
How to Clone as Derived Object in C++
Are Multiple Mutations Within Initializer Lists Undefined Behavior
How to Leverage Qt to Make a Qobject Method Thread-Safe
Understanding Boost.Spirit's String Parser
How to Build and Use Google Tensorflow C++ API
Os Specific Instructions in Cmake: How To
Difference Between Pointer to a Reference and Reference to a Pointer
Calling Python from a C++ Program for Distribution
Choosing Between Std::Map and Std::Unordered_Map
Can an Enum Class Be Converted to the Underlying Type
Std::Set with User Defined Type, How to Ensure No Duplicates