fix math functions

This commit is contained in:
bolero-MURAKAMI 2013-02-14 18:02:43 +09:00
parent 5d809ef5c9
commit fa1d769bdf
76 changed files with 582 additions and 169 deletions

View file

@ -7,6 +7,7 @@
#include <sprout/math/hyperbolic.hpp>
#include <sprout/math/exponential.hpp>
#include <sprout/math/power.hpp>
#include <sprout/math/error.hpp>
#include <sprout/math/nearest.hpp>
#include <sprout/math/remainders.hpp>
#include <sprout/math/minmax.hpp>

View file

@ -33,7 +33,7 @@ namespace sprout {
typename std::iterator_traits<Outdirected>::value_type
>::type
calc(Outdirected const& x) const {
return (1 + depth_ * sprout::sin(2 * sprout::math::pi<Value>() * rate_ * x.index() / samples_per_sec_)) * *x;
return (1 + depth_ * sprout::sin(sprout::math::two_pi<Value>() * rate_ * x.index() / samples_per_sec_)) * *x;
}
template<bool Left, typename Outdirected>
SPROUT_CONSTEXPR typename std::enable_if<
@ -41,7 +41,7 @@ namespace sprout {
typename std::iterator_traits<Outdirected>::value_type
>::type
calc(Outdirected const& x) const {
return (1 + depth_ * sprout::sin(2 * sprout::math::pi<Value>() * rate_ * x.index() / samples_per_sec_ + sprout::math::pi<Value>())) * *x;
return (1 + depth_ * sprout::sin(sprout::math::two_pi<Value>() * rate_ * x.index() / samples_per_sec_ + sprout::math::pi<Value>())) * *x;
}
public:
SPROUT_CONSTEXPR auto_pan_outdirected_value(

View file

@ -57,7 +57,7 @@ namespace sprout {
template<typename Outdirected>
SPROUT_CONSTEXPR typename std::iterator_traits<Outdirected>::value_type
operator()(Outdirected const& x) const {
return calc(x, d_ + depth_ * sprout::math::sin(2 * sprout::math::pi<Value>() * rate_ * x.index() / samples_per_sec_));
return calc(x, d_ + depth_ * sprout::math::sin(sprout::math::two_pi<Value>() * rate_ * x.index() / samples_per_sec_));
}
};

View file

@ -31,7 +31,7 @@ namespace sprout {
template<typename Outdirected>
SPROUT_CONSTEXPR typename std::iterator_traits<Outdirected>::value_type
operator()(Outdirected const& x) const {
return (1 + depth_ * sprout::math::sin(2 * sprout::math::pi<Value>() * rate_ * x.index() / samples_per_sec_)) * *x;
return (1 + depth_ * sprout::math::sin(sprout::math::two_pi<Value>() * rate_ * x.index() / samples_per_sec_)) * *x;
}
};

View file

@ -56,7 +56,7 @@ namespace sprout {
template<typename Outdirected>
SPROUT_CONSTEXPR typename std::iterator_traits<Outdirected>::value_type
operator()(Outdirected const& x) const {
return calc(x, d_ + depth_ * sprout::math::sin(2 * sprout::math::pi<Value>() * rate_ * x.index() / samples_per_sec_));
return calc(x, d_ + depth_ * sprout::math::sin(sprout::math::two_pi<Value>() * rate_ * x.index() / samples_per_sec_));
}
};

View file

@ -18,7 +18,7 @@ namespace sprout {
iir_fc(T const& fc) {
typedef typename sprout::float_promote<T>::type type;
using sprout::tan;
return tan(sprout::math::pi<type>() * fc) / (2 * sprout::math::pi<type>());
return tan(sprout::math::pi<type>() * fc) / sprout::math::two_pi<type>();
}
template<typename T>
inline SPROUT_CONSTEXPR typename sprout::float_promote<T>::type
@ -60,7 +60,7 @@ namespace sprout {
iir_lpf_impl(T const& fc, T const& q, A const& a, B const& b) {
return sprout::compost::detail::iir_lpf_impl_1<Result>(
fc, q, a, b,
2 * sprout::math::pi<T>() * fc
sprout::math::two_pi<T>() * fc
);
}
} // namespace detail
@ -112,7 +112,7 @@ namespace sprout {
iir_hpf_impl(T const& fc, T const& q, A const& a, B const& b) {
return sprout::compost::detail::iir_hpf_impl_1<Result>(
fc, q, a, b,
2 * sprout::math::pi<T>() * fc
sprout::math::two_pi<T>() * fc
);
}
} // namespace detail
@ -164,8 +164,8 @@ namespace sprout {
iir_bpf_impl(T const& fc1, T const& fc2, A const& a, B const& b) {
return sprout::compost::detail::iir_bpf_impl_1<Result>(
fc1, fc2, a, b,
2 * sprout::math::pi<T>() * (fc2 - fc1),
4 * sprout::math::pi<T>() * fc1 * fc2
sprout::math::two_pi<T>() * (fc2 - fc1),
sprout::math::four_pi<T>() * fc1 * fc2
);
}
} // namespace detail
@ -220,8 +220,8 @@ namespace sprout {
iir_bef_impl(T const& fc1, T const& fc2, A const& a, B const& b) {
return sprout::compost::detail::iir_bef_impl_1<Result>(
fc1, fc2, a, b,
2 * sprout::math::pi<T>() * (fc2 - fc1),
4 * sprout::math::pi<T>() * fc1 * fc2
sprout::math::two_pi<T>() * (fc2 - fc1),
sprout::math::four_pi<T>() * fc1 * fc2
);
}
} // namespace detail
@ -276,7 +276,7 @@ namespace sprout {
iir_resonator_impl(T const& fc, T const& q, A const& a, B const& b) {
return sprout::compost::detail::iir_resonator_impl_1<Result>(
fc, q, a, b,
2 * sprout::math::pi<T>() * fc
sprout::math::two_pi<T>() * fc
);
}
} // namespace detail
@ -328,7 +328,7 @@ namespace sprout {
iir_notch_impl(T const& fc, T const& q, A const& a, B const& b) {
return sprout::compost::detail::iir_notch_impl_1<Result>(
fc, q, a, b,
2 * sprout::math::pi<T>() * fc
sprout::math::two_pi<T>() * fc
);
}
} // namespace detail
@ -381,7 +381,7 @@ namespace sprout {
iir_low_shelving_impl(T const& fc, T const& q, T const& g, A const& a, B const& b) {
return sprout::compost::detail::iir_low_shelving_impl_1<Result>(
fc, q, a, b,
2 * sprout::math::pi<T>() * fc
sprout::math::two_pi<T>() * fc
);
}
} // namespace detail
@ -437,7 +437,7 @@ namespace sprout {
iir_high_shelving_impl(T const& fc, T const& q, T const& g, A const& a, B const& b) {
return sprout::compost::detail::iir_high_shelving_impl_1<Result>(
fc, q, a, b,
2 * sprout::math::pi<T>() * fc
sprout::math::two_pi<T>() * fc
);
}
} // namespace detail
@ -492,7 +492,7 @@ namespace sprout {
iir_peaking_impl(T const& fc, T const& q, T const& g, A const& a, B const& b) {
return sprout::compost::detail::iir_peaking_impl_1<Result>(
fc, q, a, b,
2 * sprout::math::pi<T>() * fc
sprout::math::two_pi<T>() * fc
);
}
} // namespace detail

View file

@ -53,7 +53,7 @@ namespace sprout {
, frequency_(1)
, amplitude_(1)
, phase_(0)
, d_(value_type(2) * sprout::math::pi<value_type>())
, d_(sprout::math::two_pi<value_type>())
{}
sinusoid_iterator(sinusoid_iterator const&) = default;
explicit SPROUT_CONSTEXPR sinusoid_iterator(
@ -66,7 +66,7 @@ namespace sprout {
, frequency_(frequency)
, amplitude_(amplitude)
, phase_(phase)
, d_(value_type(2) * sprout::math::pi<value_type>() * frequency)
, d_(sprout::math::two_pi<value_type>() * frequency)
{}
template<typename U>
SPROUT_CONSTEXPR sinusoid_iterator(sinusoid_iterator<U> const& it)

View file

@ -1,6 +1,7 @@
#ifndef SPROUT_MATH_ACOS_HPP
#define SPROUT_MATH_ACOS_HPP
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
@ -17,7 +18,10 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
acos(FloatType x) {
return sprout::math::half_pi<FloatType>() - sprout::math::asin(x);
return x == 1 ? FloatType(0)
: x > 1 || x < -1 ? std::numeric_limits<FloatType>::quiet_NaN()
: sprout::math::half_pi<FloatType>() - sprout::math::asin(x)
;
}
template<

View file

@ -18,7 +18,8 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
acosh(FloatType x) {
return x < 1 ? std::numeric_limits<FloatType>::quiet_NaN()
return x == 1 ? FloatType(0)
: x < 1 ? std::numeric_limits<FloatType>::quiet_NaN()
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: sprout::math::log(x + sprout::math::sqrt(x * x - 1))
;

View file

@ -7,6 +7,7 @@
#include <sprout/config.hpp>
#include <sprout/detail/pow.hpp>
#include <sprout/math/detail/config.hpp>
#include <sprout/math/detail/float_compute.hpp>
#include <sprout/math/constants.hpp>
#include <sprout/math/factorial.hpp>
#include <sprout/math/sqrt.hpp>
@ -41,8 +42,9 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
asin(FloatType x) {
typedef double type;
return x > 1 || x < -1 ? std::numeric_limits<FloatType>::quiet_NaN()
typedef typename sprout::math::detail::float_compute<FloatType>::type type;
return x == 0 ? FloatType(0)
: x > 1 || x < -1 ? std::numeric_limits<FloatType>::quiet_NaN()
: x < 0 ? -static_cast<FloatType>(sprout::math::detail::asin_impl(static_cast<type>(-x)))
: static_cast<FloatType>(sprout::math::detail::asin_impl(static_cast<type>(x)))
;

View file

@ -18,7 +18,8 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
asinh(FloatType x) {
return x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
return x == 0 ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity()
: sprout::math::log(x + sprout::math::sqrt(x * x + 1))
;

View file

@ -2,10 +2,12 @@
#define SPROUT_MATH_ATAN_HPP
#include <cstddef>
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/detail/pow.hpp>
#include <sprout/math/detail/config.hpp>
#include <sprout/math/detail/float_compute.hpp>
#include <sprout/math/constants.hpp>
#include <sprout/math/factorial.hpp>
#include <sprout/type_traits/enabler_if.hpp>
@ -39,11 +41,15 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
atan(FloatType x) {
typedef double type;
return static_cast<FloatType>(
x < 0 ? -sprout::math::detail::atan_impl(static_cast<type>(-x))
: sprout::math::detail::atan_impl(static_cast<type>(x))
);
typedef typename sprout::math::detail::float_compute<FloatType>::type type;
return x == 0 ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? sprout::math::half_pi<FloatType>()
: x == -std::numeric_limits<FloatType>::infinity() ? -sprout::math::half_pi<FloatType>()
: static_cast<FloatType>(
x < 0 ? -sprout::math::detail::atan_impl(static_cast<type>(-x))
: sprout::math::detail::atan_impl(static_cast<type>(x))
)
;
}
template<

View file

@ -1,6 +1,7 @@
#ifndef SPROUT_MATH_ATAN2_HPP
#define SPROUT_MATH_ATAN2_HPP
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
@ -18,8 +19,22 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
atan2(FloatType y, FloatType x) {
return x < 0
? sprout::math::atan(y / x) + (y < 0 ? -1 : 1) * sprout::math::pi<FloatType>()
return y == 0
? x == 0 ? FloatType(0)
: x < 0 ? sprout::math::pi<FloatType>()
: FloatType(0)
: x == 0 ? (y < 0 ? -1 : 1) * sprout::math::half_pi<FloatType>()
: x == -std::numeric_limits<FloatType>::infinity()
? y == std::numeric_limits<FloatType>::infinity() ? sprout::math::three_quarters_pi<FloatType>()
: y == -std::numeric_limits<FloatType>::infinity() ? -sprout::math::three_quarters_pi<FloatType>()
: (y < 0 ? -1 : 1) * sprout::math::half_pi<FloatType>()
: x == std::numeric_limits<FloatType>::infinity()
? y == std::numeric_limits<FloatType>::infinity() ? sprout::math::quarter_pi<FloatType>()
: y == -std::numeric_limits<FloatType>::infinity() ? -sprout::math::quarter_pi<FloatType>()
: FloatType(0)
: y == std::numeric_limits<FloatType>::infinity() ? sprout::math::half_pi<FloatType>()
: y == -std::numeric_limits<FloatType>::infinity() ? -sprout::math::half_pi<FloatType>()
: x < 0 ? sprout::math::atan(y / x) + (y < 0 ? -1 : 1) * sprout::math::pi<FloatType>()
: sprout::math::atan(y / x)
;
}

View file

@ -17,9 +17,10 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
atanh(FloatType x) {
return x < -1 || x > 1 ? std::numeric_limits<FloatType>::quiet_NaN()
: x == -1 ? -std::numeric_limits<FloatType>::infinity()
return x == 0 ? FloatType(0)
: x == 1 ? std::numeric_limits<FloatType>::infinity()
: x == -1 ? -std::numeric_limits<FloatType>::infinity()
: x > 1 || x < -1 ? std::numeric_limits<FloatType>::quiet_NaN()
: sprout::math::log((1 + x) / (1 - x)) / 2
;
}

View file

@ -1,6 +1,7 @@
#ifndef SPROUT_MATH_CBRT_HPP
#define SPROUT_MATH_CBRT_HPP
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
@ -17,7 +18,10 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
cbrt(FloatType x) {
return x < 0 ? -sprout::math::pow(-x, sprout::math::third<FloatType>())
return x == 0 ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity()
: x < 0 ? -sprout::math::pow(-x, sprout::math::third<FloatType>())
: sprout::math::pow(x, sprout::math::third<FloatType>())
;
}

View file

@ -7,7 +7,6 @@
#include <stdexcept>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
#include <sprout/math/isinf.hpp>
#include <sprout/math/equal_to.hpp>
#include <sprout/type_traits/enabler_if.hpp>
@ -27,7 +26,9 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
ceil(FloatType x) {
return sprout::math::isinf(x) ? x
return x == 0 ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity()
: std::numeric_limits<std::uintmax_t>::max() < x || std::numeric_limits<std::uintmax_t>::max() < -x
? SPROUT_MATH_THROW_LARGE_FLOAT_ROUNDING(std::domain_error("ceil: large float rounding."), x)
: x < 0 ? -static_cast<FloatType>(static_cast<std::uintmax_t>(-x))

View file

@ -7,20 +7,87 @@ namespace sprout {
namespace math {
//
// pi
// half_pi
// quarter_pi
//
template<typename T>
inline SPROUT_CONSTEXPR T pi() {
return 3.141592653589793238462643383279502884197169399375105820974944L;
return 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651L;
}
//
// half_pi
//
template<typename T>
inline SPROUT_CONSTEXPR T half_pi() {
return 1.570796326794896619231321691639751442098584699687552910487472L;
return 1.57079632679489661923132169163975144209858469968755291048747229615390820314310449931401741267105853399107404326L;
}
//
// third_pi
// two_thirds_pi
//
template<typename T>
inline SPROUT_CONSTEXPR T third_pi() {
return 1.04719755119659774615421446109316762806572313312503527365831486410260546876206966620934494178070568932738269550L;
}
template<typename T>
inline SPROUT_CONSTEXPR T two_thirds_pi() {
return 2.09439510239319549230842892218633525613144626625007054731662972820521093752413933241868988356141137865476539101L;
}
//
// quarter_pi
// three_quarters_pi
//
template<typename T>
inline SPROUT_CONSTEXPR T quarter_pi() {
return 0.785398163397448309615660845819875721049292349843776455243736L;
return 0.78539816339744830961566084581987572104929234984377645524373614807695410157155224965700870633552926699553702163L;
}
template<typename T>
inline SPROUT_CONSTEXPR T three_quarters_pi() {
return 2.35619449019234492884698253745962716314787704953132936573120844423086230471465674897102611900658780098661106488L;
}
//
// two_pi
// four_pi
//
template<typename T>
inline SPROUT_CONSTEXPR T two_pi() {
return 6.28318530717958647692528676655900576839433879875021164194988918461563281257241799725606965068423413596429617303L;
}
template<typename T>
inline SPROUT_CONSTEXPR T four_pi() {
return 12.56637061435917295385057353311801153678867759750042328389977836923126562514483599451213930136846827192859234606L;
}
//
// two_div_pi
// root_two_div_pi
//
template<typename T>
inline SPROUT_CONSTEXPR T two_div_pi() {
return 0.636619772367581343075535053490057448137838582961825794990669376235587190536906140360455211065012343824291370907L;
}
template<typename T>
inline SPROUT_CONSTEXPR T root_two_div_pi() {
return 0.797884560802865355879892119868763736951717262329869315331851659341315851798603677002504667814613872860605117725L;
}
//
// root_pi
// one_div_root_pi
// root_one_div_pi
// two_div_root_pi
//
template<typename T>
inline SPROUT_CONSTEXPR T root_pi() {
return 1.77245385090551602729816748334114518279754945612238712821380778985291128459103218137495065673854466541622682362L;
}
template<typename T>
inline SPROUT_CONSTEXPR T one_div_root_pi() {
return 0.564189583547756286948079451560772585844050629328998856844085721710642468441493414486743660202107363443028347906L;
}
template<typename T>
inline SPROUT_CONSTEXPR T root_one_div_pi() {
return 0.564189583547756286948079451560772585844050629328998856844085721710642468441493414486743660202107363443028347906L;
}
template<typename T>
inline SPROUT_CONSTEXPR T two_div_root_pi() {
return 1.128379167095512573896158903121545171688101258657997713688171443421284936882986828973487320404214726886056695812L;
}
//
// half
@ -33,11 +100,11 @@ namespace sprout {
}
template<typename T>
inline SPROUT_CONSTEXPR T third() {
return 0.3333333333333333333333333333333333333333333333333333333333333333333333L;
return 0.33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333L;
}
template<typename T>
inline SPROUT_CONSTEXPR T twothirds() {
return 0.6666666666666666666666666666666666666666666666666666666666666666666666L;
return 0.66666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666L;
}
//
// root_two
@ -45,18 +112,18 @@ namespace sprout {
//
template<typename T>
inline SPROUT_CONSTEXPR T root_two() {
return 1.414213562373095048801688724209698078569671875376948073L;
return 1.41421356237309504880168872420969807856967187537694807317667973799073247846210703885038753432764157273501384623L;
}
template<typename T>
inline SPROUT_CONSTEXPR T half_root_two() {
return 0.70710678118654752440084436210484903928483593756084L;
return 0.707106781186547524400844362104849039284835937688474036588339868995366239231053519425193767163820786367506923115L;
}
//
// e
//
template<typename T>
inline SPROUT_CONSTEXPR T e() {
return 2.7182818284590452353602874713526624977572470936999595749669676L;
return 2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642742746639193L;
}
//
// ln_ten
@ -64,11 +131,11 @@ namespace sprout {
//
template<typename T>
inline SPROUT_CONSTEXPR T ln_ten() {
return 2.302585092994045684017991454684364207601101488628772976L;
return 2.30258509299404568401799145468436420760110148862877297603332790096757260967735248023599720508959829834196778404L;
}
template<typename T>
inline SPROUT_CONSTEXPR T ln_two() {
return 0.693147180559945309417232121458176568075500134360255254L;
return 0.693147180559945309417232121458176568075500134360255254120680009493393621969694715605863326996418687542001481021L;
}
} // namespace math
} // namespace sprout

View file

@ -7,6 +7,7 @@
#include <sprout/config.hpp>
#include <sprout/detail/pow.hpp>
#include <sprout/math/detail/config.hpp>
#include <sprout/math/detail/float_compute.hpp>
#include <sprout/math/factorial.hpp>
#include <sprout/math/constants.hpp>
#include <sprout/math/fmod.hpp>
@ -27,10 +28,10 @@ namespace sprout {
template<typename FloatType>
inline SPROUT_CONSTEXPR FloatType
cos_impl(FloatType x) {
typedef double type;
typedef typename sprout::math::detail::float_compute<FloatType>::type type;
return static_cast<FloatType>(
type(1) + sprout::math::detail::cos_impl_1(
static_cast<type>(x) * static_cast<type>(x),
sprout::detail::pow2(static_cast<type>(x)),
1, sprout::math::factorial_limit<type>() / 2 + 1
)
);
@ -42,11 +43,10 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
cos(FloatType x) {
typedef double type;
return x == std::numeric_limits<FloatType>::infinity()
|| x == -std::numeric_limits<FloatType>::infinity()
? std::numeric_limits<FloatType>::quiet_NaN()
: sprout::math::detail::cos_impl(sprout::math::fmod(x, 2 * sprout::math::pi<FloatType>()))
return x == 0 ? FloatType(1)
: x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity()
? std::numeric_limits<FloatType>::quiet_NaN()
: sprout::math::detail::cos_impl(sprout::math::fmod(x, sprout::math::two_pi<FloatType>()))
;
}

View file

@ -2,10 +2,12 @@
#define SPROUT_MATH_COSH_HPP
#include <cstddef>
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/detail/pow.hpp>
#include <sprout/math/detail/config.hpp>
#include <sprout/math/detail/float_compute.hpp>
#include <sprout/math/factorial.hpp>
#include <sprout/type_traits/enabler_if.hpp>
@ -28,13 +30,17 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
cosh(FloatType x) {
typedef double type;
return static_cast<FloatType>(
type(1) + sprout::math::detail::cosh_impl(
static_cast<type>(x) * static_cast<type>(x),
1, sprout::math::factorial_limit<type>() / 2 + 1
typedef typename sprout::math::detail::float_compute<FloatType>::type type;
return x == 0 ? FloatType(1)
: x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity()
? std::numeric_limits<FloatType>::infinity()
: static_cast<FloatType>(
type(1) + sprout::math::detail::cosh_impl(
static_cast<type>(x) * static_cast<type>(x),
1, sprout::math::factorial_limit<type>() / 2 + 1
)
)
);
;
}
template<

View file

@ -0,0 +1,18 @@
#ifndef SPROUT_MATH_DETAIL_FLOAT_COMPUTE_HPP
#define SPROUT_MATH_DETAIL_FLOAT_COMPUTE_HPP
#include <sprout/config.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout {
namespace math {
namespace detail {
template<typename... Types>
struct float_compute
: public sprout::float_promote<double, Types...>
{};
} // namespace detail
} // namespace math
} // namespace sprout
#endif // #ifndef SPROUT_MATH_DETAIL_FLOAT_COMPUTE_HPP

69
sprout/math/erf.hpp Normal file
View file

@ -0,0 +1,69 @@
#ifndef SPROUT_MATH_ERF_HPP
#define SPROUT_MATH_ERF_HPP
#include <cstddef>
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/detail/pow.hpp>
#include <sprout/math/detail/config.hpp>
#include <sprout/math/detail/float_compute.hpp>
#include <sprout/math/factorial.hpp>
#include <sprout/math/constants.hpp>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout {
namespace math {
namespace detail {
template<typename T>
inline SPROUT_CONSTEXPR T
erf_impl_1(T x, std::size_t n, std::size_t last) {
return last - n == 1
? (n % 2 ? -1 : 1) / sprout::math::factorial<T>(n) / (2 * n + 1) * sprout::detail::pow_n(x, 2 * n + 1)
: sprout::math::detail::erf_impl_1(x, n, n + (last - n) / 2)
+ sprout::math::detail::erf_impl_1(x, n + (last - n) / 2, last)
;
}
template<typename T>
inline SPROUT_CONSTEXPR T
erf_impl(T x) {
return sprout::math::two_div_root_pi<T>()
* (x + sprout::math::detail::erf_impl_1(x, 1, sprout::math::factorial_limit<T>() + 1))
;
}
template<typename T>
inline SPROUT_CONSTEXPR T
erf_impl(T x2, T a) {
return T(1) - sprout::math::exp(-x2 / (T(1) + a * x2) * (sprout::math::quarter_pi<T>() + a * x2));
}
template<
typename FloatType,
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR FloatType
erf(FloatType x) {
typedef typename sprout::math::detail::float_compute<FloatType>::type type;
return x == 0 ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? FloatType(1)
: x == -std::numeric_limits<FloatType>::infinity() ? FloatType(-1)
: static_cast<FloatType>(sprout::math::detail::erf_impl(static_cast<type>(x)))
;
}
template<
typename IntType,
typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR double
erf(IntType x) {
return sprout::math::detail::erf(static_cast<double>(x));
}
} // namespace detail
using NS_SPROUT_MATH_DETAIL::erf;
} // namespace math
using sprout::math::erf;
} // namespace sprout
#endif // #ifndef SPROUT_MATH_ERF_HPP

41
sprout/math/erfc.hpp Normal file
View file

@ -0,0 +1,41 @@
#ifndef SPROUT_MATH_ERFC_HPP
#define SPROUT_MATH_ERFC_HPP
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
#include <sprout/math/erf.hpp>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout {
namespace math {
namespace detail {
template<
typename FloatType,
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR FloatType
erfc(FloatType x) {
return x == std::numeric_limits<FloatType>::infinity() ? FloatType(0)
: x == -std::numeric_limits<FloatType>::infinity() ? FloatType(2)
: FloatType(1) - sprout::math::erf(x)
;
}
template<
typename IntType,
typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR double
erfc(IntType x) {
return sprout::math::detail::erfc(static_cast<double>(x));
}
} // namespace detail
using NS_SPROUT_MATH_DETAIL::erfc;
} // namespace math
using sprout::math::erfc;
} // namespace sprout
#endif // #ifndef SPROUT_MATH_ERFC_HPP

8
sprout/math/error.hpp Normal file
View file

@ -0,0 +1,8 @@
#ifndef SPROUT_MATH_ERROR_HPP
#define SPROUT_MATH_ERROR_HPP
#include <sprout/config.hpp>
#include <sprout/math/erf.hpp>
#include <sprout/math/erfc.hpp>
#endif // #ifndef SPROUT_MATH_ERROR_HPP

View file

@ -2,10 +2,12 @@
#define SPROUT_MATH_EXP_HPP
#include <cstddef>
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/detail/pow.hpp>
#include <sprout/math/detail/config.hpp>
#include <sprout/math/detail/float_compute.hpp>
#include <sprout/math/factorial.hpp>
#include <sprout/type_traits/enabler_if.hpp>
@ -24,7 +26,7 @@ namespace sprout {
template<typename T>
inline SPROUT_CONSTEXPR T
exp_impl(T x) {
return 1 + sprout::math::detail::exp_impl_1(x, 1, sprout::math::factorial_limit<T>() + 1);
return T(1) + sprout::math::detail::exp_impl_1(x, 1, sprout::math::factorial_limit<T>() / 2 + 1);
}
template<
@ -33,8 +35,11 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
exp(FloatType x) {
typedef double type;
return !(x > -1) ? static_cast<FloatType>(1 / sprout::math::detail::exp_impl(-static_cast<type>(x)))
typedef typename sprout::math::detail::float_compute<FloatType>::type type;
return x == 0 ? FloatType(1)
: x == -std::numeric_limits<FloatType>::infinity() ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: !(x > -1) ? static_cast<FloatType>(type(1) / sprout::math::detail::exp_impl(-static_cast<type>(x)))
: static_cast<FloatType>(sprout::math::detail::exp_impl(static_cast<type>(x)))
;
}

View file

@ -1,6 +1,7 @@
#ifndef SPROUT_MATH_EXP10_HPP
#define SPROUT_MATH_EXP10_HPP
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/exp.hpp>
@ -16,7 +17,11 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
exp10(FloatType x) {
return sprout::math::exp(x * sprout::math::ln_ten<FloatType>());
return x == 0 ? FloatType(1)
: x == -std::numeric_limits<FloatType>::infinity() ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: sprout::math::exp(x * sprout::math::ln_ten<FloatType>())
;
}
template<

View file

@ -1,6 +1,7 @@
#ifndef SPROUT_MATH_EXP2_HPP
#define SPROUT_MATH_EXP2_HPP
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
@ -17,7 +18,11 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
exp2(FloatType x) {
return sprout::math::exp(x * sprout::math::ln_two<FloatType>());
return x == 0 ? FloatType(1)
: x == -std::numeric_limits<FloatType>::infinity() ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: sprout::math::exp(x * sprout::math::ln_two<FloatType>())
;
}
template<

View file

@ -1,6 +1,7 @@
#ifndef SPROUT_MATH_EXPM1_HPP
#define SPROUT_MATH_EXPM1_HPP
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
@ -17,7 +18,11 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
expm1(FloatType x) {
return sprout::math::exp(x) - 1;
return x == 0 ? FloatType(0)
: x == -std::numeric_limits<FloatType>::infinity() ? FloatType(-1)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: sprout::math::exp(x) - FloatType(1)
;
}
template<

View file

@ -8,9 +8,8 @@
#include <sprout/math/expm1.hpp>
#include <sprout/math/log.hpp>
#include <sprout/math/log10.hpp>
#include <sprout/math/log1p.hpp>
#include <sprout/math/log2.hpp>
#include <sprout/math/log1p.hpp>
#include <sprout/math/log1p.hpp>
#include <sprout/math/floating_point.hpp>
#endif // #ifndef SPROUT_MATH_EXPONENTIAL_HPP

View file

@ -1,6 +1,7 @@
#ifndef SPROUT_MATH_FLOAT2_EXPONENT_HPP
#define SPROUT_MATH_FLOAT2_EXPONENT_HPP
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
@ -16,7 +17,9 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR int
float2_exponent(FloatType x) {
return sprout::math::ilogb2(x) + 1;
return x == 0 ? 0
: sprout::math::ilogb2(x) + 1
;
}
template<

View file

@ -1,6 +1,7 @@
#ifndef SPROUT_MATH_FLOAT2_SIG_EXP_HPP
#define SPROUT_MATH_FLOAT2_SIG_EXP_HPP
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
@ -15,7 +16,13 @@ namespace sprout {
template<typename T>
inline SPROUT_CONSTEXPR sprout::pair<T, int>
float2_sig_exp_impl(T x, int exp) {
return sprout::pair<T, int>(x / sprout::detail::pow_n(T(2), exp), exp);
typedef sprout::pair<T, int> type;
return x == 0 ? type(T(0), exp)
: x == std::numeric_limits<T>::infinity() ? type(std::numeric_limits<T>::infinity(), exp)
: x == -std::numeric_limits<T>::infinity() ? type(-std::numeric_limits<T>::infinity(), exp)
: x == std::numeric_limits<T>::quiet_NaN() ? type(std::numeric_limits<T>::quiet_NaN(), exp)
: type(x / sprout::detail::pow_n(T(2), exp), exp)
;
}
template<

View file

@ -1,6 +1,7 @@
#ifndef SPROUT_MATH_FLOAT2_SIGNIFICAND_HPP
#define SPROUT_MATH_FLOAT2_SIGNIFICAND_HPP
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
@ -17,7 +18,12 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
float2_significand(FloatType x) {
return x / sprout::detail::pow_n(FloatType(2), sprout::math::float2_exponent(x));
return x == 0 ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity()
: x == std::numeric_limits<FloatType>::quiet_NaN() ? std::numeric_limits<FloatType>::quiet_NaN()
: x / sprout::detail::pow_n(FloatType(2), sprout::math::float2_exponent(x))
;
}
template<

View file

@ -1,6 +1,7 @@
#ifndef SPROUT_MATH_FLOAT_EXPONENT_HPP
#define SPROUT_MATH_FLOAT_EXPONENT_HPP
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
@ -16,7 +17,9 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR int
float_exponent(FloatType x) {
return sprout::math::ilogb(x) + 1;
return x == 0 ? 0
: sprout::math::ilogb(x) + 1
;
}
template<

View file

@ -16,7 +16,13 @@ namespace sprout {
template<typename T>
inline SPROUT_CONSTEXPR sprout::pair<T, int>
float_sig_exp_impl(T x, int exp) {
return sprout::pair<T, int>(x / sprout::detail::pow_n(T(std::numeric_limits<T>::radix), exp), exp);
typedef sprout::pair<T, int> type;
return x == 0 ? type(T(0), exp)
: x == std::numeric_limits<T>::infinity() ? type(std::numeric_limits<T>::infinity(), exp)
: x == -std::numeric_limits<T>::infinity() ? type(-std::numeric_limits<T>::infinity(), exp)
: x == std::numeric_limits<T>::quiet_NaN() ? type(std::numeric_limits<T>::quiet_NaN(), exp)
: type(x / sprout::detail::pow_n(T(std::numeric_limits<T>::radix), exp), exp)
;
}
template<

View file

@ -18,7 +18,12 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
float_significand(FloatType x) {
return x / sprout::detail::pow_n(FloatType(std::numeric_limits<FloatType>::radix), sprout::math::float_exponent(x));
return x == 0 ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity()
: x == std::numeric_limits<FloatType>::quiet_NaN() ? std::numeric_limits<FloatType>::quiet_NaN()
: x / sprout::detail::pow_n(FloatType(std::numeric_limits<FloatType>::radix), sprout::math::float_exponent(x))
;
}
template<

View file

@ -7,7 +7,6 @@
#include <stdexcept>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
#include <sprout/math/isinf.hpp>
#include <sprout/math/equal_to.hpp>
#include <sprout/type_traits/enabler_if.hpp>
@ -27,7 +26,9 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
floor(FloatType x) {
return sprout::math::isinf(x) ? x
return x == 0 ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity()
: std::numeric_limits<std::uintmax_t>::max() < x || std::numeric_limits<std::uintmax_t>::max() < -x
? SPROUT_MATH_THROW_LARGE_FLOAT_ROUNDING(std::domain_error("floor: large float rounding."), x)
: x < 0 ? sprout::math::detail::floor_impl(x, -static_cast<FloatType>(static_cast<std::uintmax_t>(-x)))

View file

@ -1,6 +1,7 @@
#ifndef SPROUT_MATH_FMAX_HPP
#define SPROUT_MATH_FMAX_HPP
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
@ -16,7 +17,7 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
fmax(FloatType x, FloatType y) {
return x < y ? y : x;
return x < y && !y == std::numeric_limits<FloatType>::quiet_NaN() ? y : x;
}
template<

View file

@ -1,6 +1,7 @@
#ifndef SPROUT_MATH_FMIN_HPP
#define SPROUT_MATH_FMIN_HPP
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
@ -16,7 +17,7 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
fmin(FloatType x, FloatType y) {
return x > y ? y : x;
return x > y && !y == std::numeric_limits<FloatType>::quiet_NaN() ? y : x;
}
template<

View file

@ -1,7 +1,7 @@
#ifndef SPROUT_MATH_FMOD_HPP
#define SPROUT_MATH_FMOD_HPP
#include <cstdint>
#include <limits>
#include <type_traits>
#include <stdexcept>
#include <sprout/config.hpp>
@ -18,7 +18,10 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
fmod(FloatType x, FloatType y) {
return y == 0 ? throw std::domain_error("fmod: divide by zero.")
return x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity() || y == 0
? std::numeric_limits<FloatType>::quiet_NaN()
: x == 0 ? FloatType(0)
: y == std::numeric_limits<FloatType>::infinity() || y == -std::numeric_limits<FloatType>::infinity() ? x
: x - sprout::math::trunc(x / y) * y
;
}

View file

@ -1,6 +1,7 @@
#ifndef SPROUT_MATH_FRAC_INT_HPP
#define SPROUT_MATH_FRAC_INT_HPP
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
@ -14,7 +15,11 @@ namespace sprout {
template<typename T>
inline SPROUT_CONSTEXPR sprout::pair<T, T>
frac_int_impl(T x, T ipart) {
return sprout::pair<T, T>(x - ipart, ipart);
typedef sprout::pair<T, T> type;
return x == std::numeric_limits<T>::infinity() || x == -std::numeric_limits<T>::infinity() ? type(T(0), ipart)
: x == std::numeric_limits<T>::quiet_NaN() ? type(std::numeric_limits<T>::quiet_NaN(), ipart)
: type(x - ipart, ipart)
;
}
template<

View file

@ -1,6 +1,7 @@
#ifndef SPROUT_MATH_FRACTIONAL_PART_HPP
#define SPROUT_MATH_FRACTIONAL_PART_HPP
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
@ -16,7 +17,10 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
fractional_part(FloatType x) {
return x - sprout::math::integer_part(x);
return x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity() ? FloatType(0)
: x == std::numeric_limits<FloatType>::quiet_NaN() ? std::numeric_limits<FloatType>::quiet_NaN()
: x - sprout::math::integer_part(x)
;
}
template<

View file

@ -7,6 +7,7 @@
#include <sprout/math/hyperbolic.hpp>
#include <sprout/math/exponential.hpp>
#include <sprout/math/power.hpp>
#include <sprout/math/error.hpp>
#include <sprout/math/nearest.hpp>
#include <sprout/math/remainders.hpp>
#include <sprout/math/minmax.hpp>

View file

@ -2,11 +2,11 @@
#define SPROUT_MATH_HYPERBOLIC_HPP
#include <sprout/config.hpp>
#include <sprout/math/sinh.hpp>
#include <sprout/math/cosh.hpp>
#include <sprout/math/tanh.hpp>
#include <sprout/math/asinh.hpp>
#include <sprout/math/acosh.hpp>
#include <sprout/math/asinh.hpp>
#include <sprout/math/atanh.hpp>
#include <sprout/math/cosh.hpp>
#include <sprout/math/sinh.hpp>
#include <sprout/math/tanh.hpp>
#endif // #ifndef SPROUT_MATH_HYPERBOLIC_HPP

View file

@ -1,11 +1,13 @@
#ifndef SPROUT_MATH_HYPOT_HPP
#define SPROUT_MATH_HYPOT_HPP
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/type_traits/float_promote.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/math/detail/config.hpp>
#include <sprout/math/fabs.hpp>
#include <sprout/math/sqrt.hpp>
namespace sprout {
@ -17,7 +19,14 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
hypot(FloatType x, FloatType y) {
return sprout::math::sqrt(x * x + y * y);
return y == 0 ? sprout::math::fabs(x)
: x == 0 ? sprout::math::fabs(y)
: y == std::numeric_limits<FloatType>::infinity() || y == -std::numeric_limits<FloatType>::infinity()
? std::numeric_limits<FloatType>::infinity()
: x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity()
? std::numeric_limits<FloatType>::infinity()
: sprout::math::sqrt(x * x + y * y)
;
}
template<

View file

@ -49,7 +49,8 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR To
iceil(FloatType x) {
return std::numeric_limits<To>::max() < x || std::numeric_limits<To>::min() > x
return x == 0 ? To(0)
: std::numeric_limits<To>::max() < x || std::numeric_limits<To>::min() > x
? SPROUT_MATH_THROW_LARGE_FLOAT_ROUNDING(std::domain_error("iceil: large float rounding."), static_cast<To>(x))
: sprout::math::detail::iceil_impl(x, static_cast<To>(x))
;

View file

@ -49,7 +49,8 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR To
ifloor(FloatType x) {
return std::numeric_limits<To>::max() < x || std::numeric_limits<To>::min() > x
return x == 0 ? To(0)
: std::numeric_limits<To>::max() < x || std::numeric_limits<To>::min() > x
? SPROUT_MATH_THROW_LARGE_FLOAT_ROUNDING(std::domain_error("ifloor: large float rounding."), static_cast<To>(x))
: sprout::math::detail::ifloor_impl(x, static_cast<To>(x))
;

View file

@ -1,6 +1,7 @@
#ifndef SPROUT_MATH_INTEGER_PART_HPP
#define SPROUT_MATH_INTEGER_PART_HPP
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
@ -16,7 +17,11 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
integer_part(FloatType x) {
return sprout::math::trunc(x);
return x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity()
: x == std::numeric_limits<FloatType>::quiet_NaN() ? std::numeric_limits<FloatType>::quiet_NaN()
: sprout::math::trunc(x)
;
}
template<

View file

@ -56,7 +56,8 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR To
iround(FloatType x) {
return std::numeric_limits<To>::max() < x || std::numeric_limits<To>::min() > x
return x == 0 ? To(0)
: std::numeric_limits<To>::max() < x || std::numeric_limits<To>::min() > x
? SPROUT_MATH_THROW_LARGE_FLOAT_ROUNDING(std::domain_error("iround: large float irounding."), x)
: x < 0 ? sprout::math::detail::iround_impl_nagative(x, static_cast<To>(x))
: sprout::math::detail::iround_impl_positive(x, static_cast<To>(x))

View file

@ -40,7 +40,8 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR To
itrunc(FloatType x) {
return std::numeric_limits<To>::max() < x || std::numeric_limits<To>::min() > x
return x == 0 ? To(0)
: std::numeric_limits<To>::max() < x || std::numeric_limits<To>::min() > x
? SPROUT_MATH_THROW_LARGE_FLOAT_ROUNDING(std::domain_error("itrunc: large float rounding."), static_cast<To>(x))
: static_cast<To>(x)
;

View file

@ -1,6 +1,7 @@
#ifndef SPROUT_MATH_LDEXP_HPP
#define SPROUT_MATH_LDEXP_HPP
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
@ -16,7 +17,12 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
ldexp(FloatType x, int exp) {
return x * sprout::detail::pow_n(FloatType(2), exp);
return x == 0 ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity()
: exp == 0 ? x
: x * sprout::detail::pow_n(FloatType(2), exp)
;
}
template<

View file

@ -7,6 +7,7 @@
#include <sprout/config.hpp>
#include <sprout/detail/pow.hpp>
#include <sprout/math/detail/config.hpp>
#include <sprout/math/detail/float_compute.hpp>
#include <sprout/math/constants.hpp>
#include <sprout/math/factorial.hpp>
#include <sprout/math/sqrt.hpp>
@ -39,9 +40,11 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
log(FloatType x) {
typedef double type;
return x == 0 ? std::numeric_limits<FloatType>::quiet_NaN()
: !(x > 0) ? -std::numeric_limits<FloatType>::infinity()
typedef typename sprout::math::detail::float_compute<FloatType>::type type;
return x == 0 ? -std::numeric_limits<FloatType>::infinity()
: x == 1 ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x < 0 ? std::numeric_limits<FloatType>::quiet_NaN()
: x < 1 ? static_cast<FloatType>(-sprout::math::detail::log_impl(1 / static_cast<type>(x)))
: static_cast<FloatType>(sprout::math::detail::log_impl(static_cast<type>(x)))
;

View file

@ -1,6 +1,7 @@
#ifndef SPROUT_MATH_LOG10_HPP
#define SPROUT_MATH_LOG10_HPP
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
@ -17,7 +18,12 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
log10(FloatType x) {
return sprout::math::log(x) / sprout::math::ln_ten<FloatType>();
return x == 0 ? -std::numeric_limits<FloatType>::infinity()
: x == 1 ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x < 0 ? std::numeric_limits<FloatType>::quiet_NaN()
: sprout::math::log(x) / sprout::math::ln_ten<FloatType>()
;
}
template<

View file

@ -1,6 +1,7 @@
#ifndef SPROUT_MATH_LOG1P_HPP
#define SPROUT_MATH_LOG1P_HPP
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
@ -16,7 +17,12 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
log1p(FloatType x) {
return sprout::math::log(1 + x);
return x == 0 ? FloatType(0)
: x == -1 ? -std::numeric_limits<FloatType>::infinity()
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x < -1 ? std::numeric_limits<FloatType>::quiet_NaN()
: sprout::math::log(1 + x)
;
}
template<

View file

@ -1,6 +1,7 @@
#ifndef SPROUT_MATH_LOG2_HPP
#define SPROUT_MATH_LOG2_HPP
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
@ -17,7 +18,12 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
log2(FloatType x) {
return sprout::math::log(x) / sprout::math::ln_two<FloatType>();
return x == 0 ? -std::numeric_limits<FloatType>::infinity()
: x == 1 ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x < 0 ? std::numeric_limits<FloatType>::quiet_NaN()
: sprout::math::log(x) / sprout::math::ln_two<FloatType>()
;
}
template<

View file

@ -90,12 +90,11 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
logb(FloatType x) {
return x < 0 ? sprout::math::detail::logb_impl(
-x, sprout::math::trunc(sprout::math::log_a(FloatType(std::numeric_limits<FloatType>::radix), -x))
)
: sprout::math::detail::logb_impl(
x, sprout::math::trunc(sprout::math::log_a(FloatType(std::numeric_limits<FloatType>::radix), x))
)
return x == 0 ? -std::numeric_limits<FloatType>::infinity()
: x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity()
? std::numeric_limits<FloatType>::infinity()
: x < 0 ? sprout::math::detail::logb_impl(-x, sprout::math::trunc(sprout::math::log_a(FloatType(std::numeric_limits<FloatType>::radix), -x)))
: sprout::math::detail::logb_impl(x, sprout::math::trunc(sprout::math::log_a(FloatType(std::numeric_limits<FloatType>::radix), x)))
;
}

View file

@ -10,6 +10,7 @@
# include <sprout/math/logb.hpp>
#else
# include <cstdint>
# include <limits>
# include <sprout/detail/pow.hpp>
# include <sprout/math/log_a.hpp>
# include <sprout/math/trunc.hpp>
@ -113,12 +114,11 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
logb2(FloatType x) {
return x < 0 ? sprout::math::detail::logb2_impl(
-x, sprout::math::trunc(sprout::math::log_a(FloatType(2), -x))
)
: sprout::math::detail::logb2_impl(
x, sprout::math::trunc(sprout::math::log_a(FloatType(2), x))
)
return x == 0 ? -std::numeric_limits<FloatType>::infinity()
: x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity()
? std::numeric_limits<FloatType>::infinity()
: x < 0 ? sprout::math::detail::logb2_impl(-x, sprout::math::trunc(sprout::math::log_a(FloatType(2), -x)))
: sprout::math::detail::logb2_impl(x, sprout::math::trunc(sprout::math::log_a(FloatType(2), x)))
;
}

View file

@ -4,12 +4,12 @@
#include <sprout/config.hpp>
#include <sprout/math/ceil.hpp>
#include <sprout/math/floor.hpp>
#include <sprout/math/trunc.hpp>
#include <sprout/math/round.hpp>
#include <sprout/math/trunc.hpp>
#include <sprout/math/iceil.hpp>
#include <sprout/math/ifloor.hpp>
#include <sprout/math/itrunc.hpp>
#include <sprout/math/iround.hpp>
#include <sprout/math/itrunc.hpp>
#include <sprout/math/lround.hpp>
#include <sprout/math/llround.hpp>

View file

@ -1,6 +1,7 @@
#ifndef SPROUT_MATH_POW_HPP
#define SPROUT_MATH_POW_HPP
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
@ -19,7 +20,29 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
pow(FloatType x, FloatType y) {
return x == 0 && y > 0 ? FloatType(0)
return x == 0
? y < 0 ? std::numeric_limits<FloatType>::infinity()
: y > 0 ? FloatType(0)
: sprout::math::exp(y * sprout::math::log(x))
: x == -1 && (y == std::numeric_limits<FloatType>::infinity() || y == -std::numeric_limits<FloatType>::infinity()) ? FloatType(1)
: x == 1 ? FloatType(1)
: y == 0 ? FloatType(1)
: y == -std::numeric_limits<FloatType>::infinity()
? x < 1 && x > -1 ? std::numeric_limits<FloatType>::infinity()
: x > 1 || x < -1 ? FloatType(0)
: sprout::math::exp(y * sprout::math::log(x))
: y == std::numeric_limits<FloatType>::infinity()
? x < 1 && x > -1 ? FloatType(0)
: x > 1 || x < -1 ? std::numeric_limits<FloatType>::infinity()
: sprout::math::exp(y * sprout::math::log(x))
: x == -std::numeric_limits<FloatType>::infinity()
? y < 0 ? FloatType(0)
: y > 0 ? std::numeric_limits<FloatType>::infinity()
: sprout::math::exp(y * sprout::math::log(x))
: x == std::numeric_limits<FloatType>::infinity()
? y < 0 ? FloatType(0)
: y > 0 ? std::numeric_limits<FloatType>::infinity()
: sprout::math::exp(y * sprout::math::log(x))
: sprout::math::exp(y * sprout::math::log(x))
;
}

View file

@ -2,12 +2,12 @@
#define SPROUT_MATH_POWER_HPP
#include <sprout/config.hpp>
#include <sprout/math/sqrt.hpp>
#include <sprout/math/cbrt.hpp>
#include <sprout/math/pow.hpp>
#include <sprout/math/log_a.hpp>
#include <sprout/math/hypot.hpp>
#include <sprout/math/abs.hpp>
#include <sprout/math/fabs.hpp>
#include <sprout/math/abs.hpp>
#include <sprout/math/hypot.hpp>
#include <sprout/math/pow.hpp>
#include <sprout/math/sqrt.hpp>
#include <sprout/math/log_a.hpp>
#endif // #ifndef SPROUT_MATH_POWER_HPP

View file

@ -1,7 +1,7 @@
#ifndef SPROUT_MATH_QUOTIENT_HPP
#define SPROUT_MATH_QUOTIENT_HPP
#include <cstdint>
#include <limits>
#include <type_traits>
#include <stdexcept>
#include <sprout/config.hpp>
@ -20,7 +20,10 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR R
quotient(FloatType x, FloatType y) {
return y == 0 ? throw std::domain_error("quotient: divide by zero.")
return x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity() || y == 0
? std::numeric_limits<FloatType>::quiet_NaN()
: x == 0 ? FloatType(0)
: y == std::numeric_limits<FloatType>::infinity() || y == -std::numeric_limits<FloatType>::infinity() ? FloatType(0)
: sprout::math::iround<R>(x / y)
;
}

View file

@ -1,7 +1,7 @@
#ifndef SPROUT_MATH_REM_QUO_HPP
#define SPROUT_MATH_REM_QUO_HPP
#include <cstdint>
#include <limits>
#include <type_traits>
#include <stdexcept>
#include <sprout/config.hpp>
@ -17,7 +17,13 @@ namespace sprout {
template<typename R, typename T>
inline SPROUT_CONSTEXPR sprout::pair<T, R>
rem_quo_impl(T x, T y, R quo) {
return sprout::pair<T, T>(x - quo * y, quo);
typedef sprout::pair<T, R> type;
return x == std::numeric_limits<T>::infinity() || x == -std::numeric_limits<T>::infinity() || y == 0
? type(std::numeric_limits<T>::quiet_NaN(), quo)
: x == 0 ? type(T(0), quo)
: y == std::numeric_limits<T>::infinity() || y == -std::numeric_limits<T>::infinity() ? type(x, quo)
: type(x - quo * y, quo)
;
}
template<
typename R = int,

View file

@ -1,7 +1,7 @@
#ifndef SPROUT_MATH_REMAINDER_HPP
#define SPROUT_MATH_REMAINDER_HPP
#include <cstdint>
#include <limits>
#include <type_traits>
#include <stdexcept>
#include <sprout/config.hpp>
@ -19,7 +19,10 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
remainder(FloatType x, FloatType y) {
return y == 0 ? throw std::domain_error("remainder: divide by zero.")
return x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity() || y == 0
? std::numeric_limits<FloatType>::quiet_NaN()
: x == 0 ? FloatType(0)
: y == std::numeric_limits<FloatType>::infinity() || y == -std::numeric_limits<FloatType>::infinity() ? x
: x - sprout::math::round(x / y) * y
;
}

View file

@ -7,7 +7,6 @@
#include <stdexcept>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
#include <sprout/math/isinf.hpp>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout {
@ -33,7 +32,9 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
round(FloatType x) {
return sprout::math::isinf(x) ? x
return x == 0 ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity()
: std::numeric_limits<std::uintmax_t>::max() < x || std::numeric_limits<std::uintmax_t>::max() < -x
? SPROUT_MATH_THROW_LARGE_FLOAT_ROUNDING(std::domain_error("round: large float rounding."), x)
: x < 0 ? sprout::math::detail::round_impl_nagative(x, -static_cast<FloatType>(static_cast<std::uintmax_t>(-x)))

View file

@ -17,7 +17,12 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
scalbln(FloatType x, long exp) {
return x * sprout::detail::pow_n(FloatType(std::numeric_limits<FloatType>::radix), exp);
return x == 0 ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity()
: exp == 0 ? x
: x * sprout::detail::pow_n(FloatType(std::numeric_limits<FloatType>::radix), exp)
;
}
template<

View file

@ -17,7 +17,12 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
scalbn(FloatType x, int exp) {
return x * sprout::detail::pow_n(FloatType(std::numeric_limits<FloatType>::radix), exp);
return x == 0 ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity()
: exp == 0 ? x
: x * sprout::detail::pow_n(FloatType(std::numeric_limits<FloatType>::radix), exp)
;
}
template<

View file

@ -1,6 +1,7 @@
#ifndef SPROUT_MATH_SIN_HPP
#define SPROUT_MATH_SIN_HPP
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
@ -17,7 +18,11 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
sin(FloatType x) {
return -sprout::math::cos(x + sprout::math::half_pi<FloatType>());
return x == 0 ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity()
? std::numeric_limits<FloatType>::quiet_NaN()
: -sprout::math::cos(x + sprout::math::half_pi<FloatType>())
;
}
template<

View file

@ -2,10 +2,12 @@
#define SPROUT_MATH_SINH_HPP
#include <cstddef>
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/detail/pow.hpp>
#include <sprout/math/detail/config.hpp>
#include <sprout/math/detail/float_compute.hpp>
#include <sprout/math/factorial.hpp>
#include <sprout/type_traits/enabler_if.hpp>
@ -28,13 +30,17 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
sinh(FloatType x) {
typedef double type;
return static_cast<FloatType>(
static_cast<type>(x) + sprout::math::detail::sinh_impl(
static_cast<type>(x),
1, (sprout::math::factorial_limit<type>() - 1) / 2 + 1
typedef typename sprout::math::detail::float_compute<FloatType>::type type;
return x == 0 ? FloatType(1)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity()
: static_cast<FloatType>(
static_cast<type>(x) + sprout::math::detail::sinh_impl(
static_cast<type>(x),
1, (sprout::math::factorial_limit<type>() - 1) / 2 + 1
)
)
);
;
}
template<

View file

@ -5,6 +5,7 @@
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
#include <sprout/math/detail/float_compute.hpp>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout {
@ -14,22 +15,13 @@ namespace sprout {
inline SPROUT_CONSTEXPR T
sqrt_impl_1(T x, T s, T s2) {
return !(s < s2) ? s2
: sprout::math::detail::sqrt_impl_1(
x,
(x / s + s) / 2,
s
)
: sprout::math::detail::sqrt_impl_1(x, (x / s + s) / 2, s)
;
}
template<typename T>
inline SPROUT_CONSTEXPR T
sqrt_impl(T x, T s) {
return sprout::math::detail::sqrt_impl_1(
x,
(x / s + s) / 2,
s
)
;
return sprout::math::detail::sqrt_impl_1(x, (x / s + s) / 2, s);
}
template<
@ -38,13 +30,12 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
sqrt(FloatType x) {
typedef double type;
return x < 0 ? std::numeric_limits<FloatType>::quiet_NaN()
: x == 0 ? type(0)
: static_cast<FloatType>(sprout::math::detail::sqrt_impl(
static_cast<type>(x),
x > 1 ? static_cast<type>(x) : type(1)
));
typedef typename sprout::math::detail::float_compute<FloatType>::type type;
return x == 0 ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x == std::numeric_limits<FloatType>::quiet_NaN() ? std::numeric_limits<FloatType>::quiet_NaN()
: x < 0 ? std::numeric_limits<FloatType>::quiet_NaN()
: static_cast<FloatType>(sprout::math::detail::sqrt_impl(static_cast<type>(x), x > 1 ? static_cast<type>(x) : type(1)));
}
template<

View file

@ -1,6 +1,7 @@
#ifndef SPROUT_MATH_TAN_HPP
#define SPROUT_MATH_TAN_HPP
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
@ -17,7 +18,11 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
tan(FloatType x) {
return sprout::math::sin(x) / sprout::math::cos(x);
return x == 0 ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity()
? std::numeric_limits<FloatType>::quiet_NaN()
: sprout::math::sin(x) / sprout::math::cos(x)
;
}
template<

View file

@ -1,6 +1,7 @@
#ifndef SPROUT_MATH_TANH_HPP
#define SPROUT_MATH_TANH_HPP
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
@ -17,7 +18,11 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
tanh(FloatType x) {
return sprout::math::sinh(x) / sprout::math::cosh(x);
return x == 0 ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? FloatType(1)
: x == -std::numeric_limits<FloatType>::infinity() ? FloatType(-1)
: sprout::math::sinh(x) / sprout::math::cosh(x)
;
}
template<

View file

@ -2,12 +2,12 @@
#define SPROUT_MATH_TRIGONOMETRIC_HPP
#include <sprout/config.hpp>
#include <sprout/math/sin.hpp>
#include <sprout/math/cos.hpp>
#include <sprout/math/tan.hpp>
#include <sprout/math/asin.hpp>
#include <sprout/math/acos.hpp>
#include <sprout/math/asin.hpp>
#include <sprout/math/atan.hpp>
#include <sprout/math/atan2.hpp>
#include <sprout/math/cos.hpp>
#include <sprout/math/sin.hpp>
#include <sprout/math/tan.hpp>
#endif // #ifndef SPROUT_MATH_TRIGONOMETRIC_HPP

View file

@ -7,7 +7,6 @@
#include <stdexcept>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
#include <sprout/math/isinf.hpp>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout {
@ -19,7 +18,9 @@ namespace sprout {
>
inline SPROUT_CONSTEXPR FloatType
trunc(FloatType x) {
return sprout::math::isinf(x) ? x
return x == 0 ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity()
: std::numeric_limits<std::uintmax_t>::max() < x || std::numeric_limits<std::uintmax_t>::max() < -x
? SPROUT_MATH_THROW_LARGE_FLOAT_ROUNDING(std::domain_error("trunc: large float rounding."), x)
: x < 0 ? -static_cast<FloatType>(static_cast<std::uintmax_t>(-x))

View file

@ -21,7 +21,7 @@ namespace sprout {
return sprout::detail::dft_element_gen(
first,
last,
-(2 * sprout::math::pi<elem_type>() * i / size)
-(sprout::math::two_pi<elem_type>() * i / size)
);
}
} // namespace detail

View file

@ -50,7 +50,7 @@ namespace sprout {
typedef typename sprout::container_traits<Container>::value_type value_type;
return sprout::fixed::detail::sinusoid_impl(
cont,
value_type(2) * sprout::math::pi<value_type>() * frequency / value_type(sprout::size(cont)),
sprout::math::two_pi<value_type>() * frequency / value_type(sprout::size(cont)),
amplitude,
phase,
sprout::container_indexes<Container>::make(),

View file

@ -22,7 +22,7 @@ namespace sprout {
triangle_value(T const& t) {
using sprout::sin;
using sprout::asin;
return T(2) / T(sprout::math::pi<double>()) * asin(sin(T(2) * T(sprout::math::pi<double>()) * t));
return T(sprout::math::two_div_pi<double>()) * asin(sin(T(sprout::math::two_pi<double>()) * t));
}
template<typename Container, sprout::index_t... Indexes>

View file

@ -21,7 +21,7 @@ namespace sprout {
return sprout::detail::dft_element_gen(
first,
last,
2 * sprout::math::pi<elem_type>() * i / size
sprout::math::two_pi<elem_type>() * i / size
)
/ static_cast<elem_type>(size)
;

View file

@ -127,8 +127,8 @@ namespace sprout {
return sprout::random::random_result<Engine, normal_distribution>(
cached_rho
* (valid
? sprout::cos(result_type(2) * sprout::math::pi<result_type>() * r1)
: sprout::sin(result_type(2) * sprout::math::pi<result_type>() * r1)
? sprout::cos(sprout::math::two_pi<result_type>() * r1)
: sprout::sin(sprout::math::two_pi<result_type>() * r1)
)
* sigma_ + mean_,
eng,