constexpr exp, log, pow

2020-06-07 05:47发布

问题:

I'd like to use constexpr versions of standard <cmath> functions like exp, log, pow in a portable way. I currently have a non-portable solution g++ treats these functions as constexpr - a non-compliant extension of C++, but I am concerned about portability and future-proofing (I imagine that this extension might one day be removed from g++).

I am interested in constexpr versions of these functions, not template metaprograms - I want the same functionality to be available both at compile time and runtime. I do not need C compatibility, but I do need fast implementations - naive implementations such as Taylor Series expansions would be too slow.

How can I implement such functionalities? I am specifically interested in exp, log, and pow

Some tangentially related things I've learned from my research

  • The standard-compliant versions of these functions aren't technically constexpr because they must have side-effects (e.g. setting errno) to maintain C compatibility
  • In C++11, an implementation was allowed to make these functions constexpr, but as of C++14, this is prohibited (per the first answer to this question and the answer to this question). This is part of the reason that I am concerned that the functions may not be constexpr in future versions of g++
  • g++'s implementation of each math function foo just calls a built-in function __builtin_foo, which is treated as constexpr. I could perhaps start calling the __builtin_foo functions rather than the foo functions - these might remain constexpr in future versions of g++ even if the corresponding foo functions are made compliant - but this only helps with future-proofing, not with portability.

回答1:

Have you ever watch Sprout's implementaion?

Sprout is header-only library that provide C++11/14 constexpr based Containers, Algorithms, Random numbers, Parsing, Ray tracing, Synthesizer, and others.

https://github.com/bolero-MURAKAMI/Sprout/tree/master/sprout/math