add math: reminder, rem_quo(same as remquo)

This commit is contained in:
bolero-MURAKAMI 2013-02-10 17:12:31 +09:00
parent 434aa8d3c5
commit 887dba1849
9 changed files with 189 additions and 35 deletions

View file

@ -15,8 +15,8 @@
#include <sprout/math/float2_significand.hpp> #include <sprout/math/float2_significand.hpp>
#include <sprout/math/float2_exponent.hpp> #include <sprout/math/float2_exponent.hpp>
#include <sprout/math/float2_sig_exp.hpp> #include <sprout/math/float2_sig_exp.hpp>
#include <sprout/math/float_fractional_part.hpp> #include <sprout/math/fractional_part.hpp>
#include <sprout/math/float_integer_part.hpp> #include <sprout/math/integer_part.hpp>
#include <sprout/math/float_frac_int.hpp> #include <sprout/math/frac_int.hpp>
#endif // #ifndef SPROUT_MATH_FLOATING_POINT_HPP #endif // #ifndef SPROUT_MATH_FLOATING_POINT_HPP

View file

@ -5,7 +5,6 @@
#include <type_traits> #include <type_traits>
#include <stdexcept> #include <stdexcept>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/math/isinf.hpp>
#include <sprout/math/trunc.hpp> #include <sprout/math/trunc.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp> #include <sprout/type_traits/float_promote.hpp>

View file

@ -1,10 +1,10 @@
#ifndef SPROUT_MATH_FLOAT_FRAC_INT_HPP #ifndef SPROUT_MATH_FRAC_INT_HPP
#define SPROUT_MATH_FLOAT_FRAC_INT_HPP #define SPROUT_MATH_FRAC_INT_HPP
#include <type_traits> #include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp> #include <sprout/math/detail/config.hpp>
#include <sprout/math/float_integer_part.hpp> #include <sprout/math/integer_part.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
#include <sprout/utility/pair/pair.hpp> #include <sprout/utility/pair/pair.hpp>
@ -13,7 +13,7 @@ namespace sprout {
namespace detail { namespace detail {
template<typename T> template<typename T>
inline SPROUT_CONSTEXPR sprout::pair<T, T> inline SPROUT_CONSTEXPR sprout::pair<T, T>
float_frac_int_impl(T x, T ipart) { frac_int_impl(T x, T ipart) {
return sprout::pair<T, T>(x - ipart, ipart); return sprout::pair<T, T>(x - ipart, ipart);
} }
@ -22,8 +22,8 @@ namespace sprout {
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
> >
inline SPROUT_CONSTEXPR sprout::pair<FloatType, FloatType> inline SPROUT_CONSTEXPR sprout::pair<FloatType, FloatType>
float_frac_int(FloatType x) { frac_int(FloatType x) {
return sprout::math::detail::float_frac_int_impl(x, sprout::math::float_integer_part(x)); return sprout::math::detail::frac_int_impl(x, sprout::math::integer_part(x));
} }
template< template<
@ -31,15 +31,15 @@ namespace sprout {
typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler
> >
inline SPROUT_CONSTEXPR sprout::pair<double, double> inline SPROUT_CONSTEXPR sprout::pair<double, double>
float_frac_int(IntType x) { frac_int(IntType x) {
return sprout::math::detail::float_frac_int(static_cast<double>(x)); return sprout::math::detail::frac_int(static_cast<double>(x));
} }
} // namespace detail } // namespace detail
using sprout::math::detail::float_frac_int; using sprout::math::detail::frac_int;
} // namespace math } // namespace math
using sprout::math::float_frac_int; using sprout::math::frac_int;
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_MATH_FLOAT_FRAC_INT_HPP #endif // #ifndef SPROUT_MATH_FRAC_INT_HPP

View file

@ -1,10 +1,10 @@
#ifndef SPROUT_MATH_FLOAT_INTEGER_PART_HPP #ifndef SPROUT_MATH_FRACTIONAL_PART_HPP
#define SPROUT_MATH_FLOAT_INTEGER_PART_HPP #define SPROUT_MATH_FRACTIONAL_PART_HPP
#include <type_traits> #include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp> #include <sprout/math/detail/config.hpp>
#include <sprout/math/floor.hpp> #include <sprout/math/integer_part.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
namespace sprout { namespace sprout {
@ -15,8 +15,8 @@ namespace sprout {
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
> >
inline SPROUT_CONSTEXPR FloatType inline SPROUT_CONSTEXPR FloatType
float_integer_part(FloatType x) { fractional_part(FloatType x) {
return sprout::math::floor(x); return x - sprout::math::integer_part(x);
} }
template< template<
@ -24,15 +24,15 @@ namespace sprout {
typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler
> >
inline SPROUT_CONSTEXPR double inline SPROUT_CONSTEXPR double
float_integer_part(IntType x) { fractional_part(IntType x) {
return sprout::math::detail::float_integer_part(static_cast<double>(x)); return sprout::math::detail::fractional_part(static_cast<double>(x));
} }
} // namespace detail } // namespace detail
using sprout::math::detail::float_integer_part; using sprout::math::detail::fractional_part;
} // namespace math } // namespace math
using sprout::math::float_integer_part; using sprout::math::fractional_part;
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_MATH_FLOAT_INTEGER_PART_HPP #endif // #ifndef SPROUT_MATH_FRACTIONAL_PART_HPP

View file

@ -1,10 +1,10 @@
#ifndef SPROUT_MATH_FLOAT_FRACTIONAL_PART_HPP #ifndef SPROUT_MATH_INTEGER_PART_HPP
#define SPROUT_MATH_FLOAT_FRACTIONAL_PART_HPP #define SPROUT_MATH_INTEGER_PART_HPP
#include <type_traits> #include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp> #include <sprout/math/detail/config.hpp>
#include <sprout/math/float_integer_part.hpp> #include <sprout/math/trunc.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
namespace sprout { namespace sprout {
@ -15,8 +15,8 @@ namespace sprout {
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
> >
inline SPROUT_CONSTEXPR FloatType inline SPROUT_CONSTEXPR FloatType
float_fractional_part(FloatType x) { integer_part(FloatType x) {
return x - sprout::math::float_integer_part(x); return sprout::math::trunc(x);
} }
template< template<
@ -24,15 +24,15 @@ namespace sprout {
typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler
> >
inline SPROUT_CONSTEXPR double inline SPROUT_CONSTEXPR double
float_fractional_part(IntType x) { integer_part(IntType x) {
return sprout::math::detail::float_fractional_part(static_cast<double>(x)); return sprout::math::detail::integer_part(static_cast<double>(x));
} }
} // namespace detail } // namespace detail
using sprout::math::detail::float_fractional_part; using sprout::math::detail::integer_part;
} // namespace math } // namespace math
using sprout::math::float_fractional_part; using sprout::math::integer_part;
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_MATH_FLOAT_FRACTIONAL_PART_HPP #endif // #ifndef SPROUT_MATH_INTEGER_PART_HPP

View file

@ -9,5 +9,8 @@
#include <sprout/math/fmin.hpp> #include <sprout/math/fmin.hpp>
#include <sprout/math/fdim.hpp> #include <sprout/math/fdim.hpp>
#include <sprout/math/fmod.hpp> #include <sprout/math/fmod.hpp>
#include <sprout/math/reminder.hpp>
#include <sprout/math/quotient.hpp>
#include <sprout/math/rem_quo.hpp>
#endif // #ifndef SPROUT_MATH_OPERATIONS_HPP #endif // #ifndef SPROUT_MATH_OPERATIONS_HPP

49
sprout/math/quotient.hpp Normal file
View file

@ -0,0 +1,49 @@
#ifndef SPROUT_MATH_QUOTIENT_HPP
#define SPROUT_MATH_QUOTIENT_HPP
#include <cstdint>
#include <type_traits>
#include <stdexcept>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
#include <sprout/math/iround.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
namespace sprout {
namespace math {
namespace detail {
template<
typename R = int,
typename FloatType,
typename sprout::enabler_if<std::is_floating_point<FloatType>::value && std::is_integral<R>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR R
quotient(FloatType x, FloatType y) {
return y == 0 ? throw std::domain_error("quotient: divide by zero.")
: sprout::math::iround<R>(x / y)
;
}
template<
typename R = int,
typename ArithmeticType1,
typename ArithmeticType2,
typename sprout::enabler_if<
std::is_arithmetic<ArithmeticType1>::value && std::is_arithmetic<ArithmeticType2>::value && std::is_integral<R>::value
>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR R
quotient(ArithmeticType1 x, ArithmeticType2 y) {
typedef typename sprout::float_promote<ArithmeticType1, ArithmeticType2>::type type;
return sprout::math::detail::quotient(static_cast<type>(x), static_cast<type>(y));
}
} // namespace detail
using sprout::math::detail::quotient;
} // namespace math
using sprout::math::quotient;
} // namespace sprout
#endif // #ifndef SPROUT_MATH_QUOTIENT_HPP

56
sprout/math/rem_quo.hpp Normal file
View file

@ -0,0 +1,56 @@
#ifndef SPROUT_MATH_REM_QUO_HPP
#define SPROUT_MATH_REM_QUO_HPP
#include <cstdint>
#include <type_traits>
#include <stdexcept>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
#include <sprout/math/quotient.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.hpp>
#include <sprout/utility/pair/pair.hpp>
namespace sprout {
namespace math {
namespace detail {
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);
}
template<
typename R = int,
typename FloatType,
typename sprout::enabler_if<std::is_floating_point<FloatType>::value && std::is_integral<R>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR sprout::pair<FloatType, R>
rem_quo(FloatType x, FloatType y) {
return sprout::math::detail::rem_quo_impl(x, y, sprout::math::quotient(x, y));
}
template<
typename R = int,
typename ArithmeticType1,
typename ArithmeticType2,
typename sprout::enabler_if<
std::is_arithmetic<ArithmeticType1>::value && std::is_arithmetic<ArithmeticType2>::value && std::is_integral<R>::value
>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR sprout::pair<
typename sprout::float_promote<ArithmeticType1, ArithmeticType2>::type,
R
>
rem_quo(ArithmeticType1 x, ArithmeticType2 y) {
typedef typename sprout::float_promote<ArithmeticType1, ArithmeticType2>::type type;
return sprout::math::detail::rem_quo(static_cast<type>(x), static_cast<type>(y));
}
} // namespace detail
using sprout::math::detail::rem_quo;
} // namespace math
using sprout::math::rem_quo;
} // namespace sprout
#endif // #ifndef SPROUT_MATH_REM_QUO_HPP

47
sprout/math/reminder.hpp Normal file
View file

@ -0,0 +1,47 @@
#ifndef SPROUT_MATH_REMAINDER_HPP
#define SPROUT_MATH_REMAINDER_HPP
#include <cstdint>
#include <type_traits>
#include <stdexcept>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
#include <sprout/math/round.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/type_traits/float_promote.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
remainder(FloatType x, FloatType y) {
return y == 0 ? throw std::domain_error("remainder: divide by zero.")
: x - sprout::math::round(x / y) * y
;
}
template<
typename ArithmeticType1,
typename ArithmeticType2,
typename sprout::enabler_if<
std::is_arithmetic<ArithmeticType1>::value && std::is_arithmetic<ArithmeticType2>::value
>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType1, ArithmeticType2>::type
remainder(ArithmeticType1 x, ArithmeticType2 y) {
typedef typename sprout::float_promote<ArithmeticType1, ArithmeticType2>::type type;
return sprout::math::detail::remainder(static_cast<type>(x), static_cast<type>(y));
}
} // namespace detail
using NS_SPROUT_MATH_DETAIL::remainder;
} // namespace math
using sprout::math::remainder;
} // namespace sprout
#endif // #ifndef SPROUT_MATH_REMAINDER_HPP