-
Notifications
You must be signed in to change notification settings - Fork 23
Description
It seems like that the cmath.inl::get_fast_converge_params algorithm is using an integer intermediate (size_t) representation, where not all floats can be represented with.
template<typename Float>
static constexpr auto get_fast_converge_params(Float* const A, std::size_t* const n, Float x)
-> void
{
auto _x = static_cast<std::size_t>(trunc(x));
auto _n = static_cast<std::size_t>(logi_helper<10>(_x));
*n = _n;
*A = x / pow_helper(10, _n);
}
The following code will lead to compile-time errors (compiled with gcc 10.3.0):
static_assert(smath::log2(1.0e8) < 27, "");
/workspace/test/static_math(master*) # make
Consolidate compiler generated dependencies of target test-cmath
[ 6%] Building CXX object CMakeFiles/test-cmath.dir/test/cmath.cpp.o
/workspace/test/static_math/test/cmath.cpp: In function ‘int main()’:
/workspace/test/static_math/test/cmath.cpp:132:38: error: non-constant condition for static assertion
132 | static_assert(smath::log2(1.0e8) < 27, "");
| ~~~~~~~~~~~~~~~~~~~^~~~
/workspace/test/static_math/test/cmath.cpp:132:30: in ‘constexpr’ expansion of ‘smath::log2(1.0e+8)’
/workspace/test/static_math/include/static_math/detail/cmath.inl:664:38: in ‘constexpr’ expansion of ‘smath::detail::log2_helper(x)’
/workspace/test/static_math/include/static_math/detail/cmath.inl:361:27: in ‘constexpr’ expansion of ‘smath::detail::log2_helper((std::is_floating_point(), std::integral_constant<bool, true>()), x)’
/workspace/test/static_math/include/static_math/detail/cmath.inl:354:35: in ‘constexpr’ expansion of ‘smath::detail::logf_helper(x)’
/workspace/test/static_math/include/static_math/detail/cmath.inl:318:49: in ‘constexpr’ expansion of ‘smath::detail::fast_converge_log<0>::compute(x)’
/workspace/test/static_math/include/static_math/detail/cmath.inl:266:37: in ‘constexpr’ expansion of ‘smath::detail::get_fast_converge_params((& a), (& n), x)’
/workspace/test/static_math/include/static_math/detail/cmath.inl:251:28: in ‘constexpr’ expansion of ‘smath::detail::pow_helper<int, long unsigned int>(10, _n)’
/workspace/test/static_math/include/static_math/detail/cmath.inl:54:45: in ‘constexpr’ expansion of ‘smath::detail::pow_helper<int, long unsigned int>((x * x), (exponent / 2))’
/workspace/test/static_math/include/static_math/detail/cmath.inl:54:45: in ‘constexpr’ expansion of ‘smath::detail::pow_helper<int, long unsigned int>((x * x), (exponent / 2))’
/workspace/test/static_math/include/static_math/detail/cmath.inl:54:45: in ‘constexpr’ expansion of ‘smath::detail::pow_helper<int, long unsigned int>((x * x), (exponent / 2))’
/workspace/test/static_math/test/cmath.cpp:132:38: error: overflow in constant expression [-fpermissive]
make[2]: *** [CMakeFiles/test-cmath.dir/build.make:76: CMakeFiles/test-cmath.dir/test/cmath.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:396: CMakeFiles/test-cmath.dir/all] Error 2
make: *** [Makefile:146: all] Error 2
Changing this to
template<typename Float> static constexpr auto get_fast_converge_params(Float* const A, std::size_t* const n, Float x)
-> void
{
auto _x = static_cast<std::size_t>(trunc(x));
auto _n = static_cast<std::size_t>(logi_helper<10>(_x));
*n = _n;
*A = x / pow_helper<int long long>(10, _n);
}
will fix this issue for the particular case, but for values > std::numeric_limits<size_t> this will break.
static_assert(smath::log10(2.0e20) > 0, ""); leads to:
/workspace/test/static_math(master*) # make
[ 6%] Building CXX object CMakeFiles/test-cmath.dir/test/cmath.cpp.o
/workspace/test/static_math/test/cmath.cpp: In function ‘int main()’:
/workspace/test/static_math/test/cmath.cpp:133:40: error: non-constant condition for static assertion
133 | static_assert(smath::log10(2.0e20) > 0, "");
| ~~~~~~~~~~~~~~~~~~~~~^~~
/workspace/test/static_math/test/cmath.cpp:133:31: in ‘constexpr’ expansion of ‘smath::log10(2.0e+20)’
/workspace/test/static_math/include/static_math/detail/cmath.inl:525:39: in ‘constexpr’ expansion of ‘smath::detail::log10_helper(x)’
/workspace/test/static_math/include/static_math/detail/cmath.inl:278:24: in ‘constexpr’ expansion of ‘smath::detail::log10_helper((std::is_floating_point(), std::integral_constant<bool, true>()), x)’
/workspace/test/static_math/include/static_math/detail/cmath.inl:273:31: in ‘constexpr’ expansion of ‘smath::detail::logf_helper(x)’
/workspace/test/static_math/include/static_math/detail/cmath.inl:262:45: in ‘constexpr’ expansion of ‘smath::detail::fast_converge_log<0>::compute(x)’
/workspace/test/static_math/include/static_math/detail/cmath.inl:219:33: in ‘constexpr’ expansion of ‘smath::detail::get_fast_converge_params((& a), (& n), x)’
/workspace/test/static_math/include/static_math/detail/cmath.inl:204:45: in ‘constexpr’ expansion of ‘smath::trunc(x)’
/workspace/test/static_math/test/cmath.cpp:133:40: error: overflow in constant expression [-fpermissive]
/workspace/test/static_math/test/cmath.cpp:133:40: error: overflow in constant expression [-fpermissive]
/workspace/test/static_math/test/cmath.cpp:133:40: error: overflow in constant expression [-fpermissive]
make[2]: *** [CMakeFiles/test-cmath.dir/build.make:76: CMakeFiles/test-cmath.dir/test/cmath.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:396: CMakeFiles/test-cmath.dir/all] Error 2
make: *** [Makefile:146: all] Error 2