math_utils.hpp
This header file provides various mathematical utilities, including functions for fundamental mathematical operations, and constants.
It also provides the QuadReal class for quadruple-precision floating-point numbers when
SCTL_QUAD_T is defined (e.g. with GCC we can use the compiler flag -DSCTL_QUAD_T=__float128).
Classes and Types
-
class QuadReal
Class representing a quadruple precision floating-point number. To enable, the macro
SCTL_QUAD_Tmust be defined and set equal to the compiler supported quad-precision floating point type (e.g. with GCC use the compiler flag:-DSCTL_QUAD_T=__float128).
Constructor:
QuadReal(): Default constructor.
QuadReal(const QuadReal& v): Copy constructor.
template <class ValueType> QuadReal(ValueType v): Constructor with explicit conversion from another type.Methods:
operator=: Copy assignment operator.
operator ValueType() const: Explicit conversion operator to another type.
operator+=,operator-=,operator*=,operator/=: In-place arithmetic operations with another QuadReal.
operator+,operator-,operator*,operator/: Arithmetic operations with another QuadReal.
operator-: Unary negation operator.
operator<,operator>,operator!=,operator==,operator<=,operator>=: Comparison operators.
friend operator+,friend operator-,friend operator*,friend operator/: Arithmetic operations with QuadRealType.
friend operator<,friend operator>,friend operator!=,friend operator==,friend operator<=,friend operator>=: Comparison operators with QuadRealType.
friend trunc(const QuadReal): Truncates a QuadReal.
Functions
Mathematical Constants:
template <class Real> constexpr Real const_pi(): Returns the mathematical constant pi.template <class Real> constexpr Real const_e(): Returns the mathematical constant e.template <class Real> constexpr Real machine_eps(): Returns the machine epsilon forReal.
Basic Operations:
template <class Real> Real fabs(const Real a): Returns the absolute value of the input.template <class Real> Real trunc(const Real a): Truncates the input real number to the nearest integer towards zero.template <class Real> Real round(const Real a): Rounds the input real number to the nearest integer.template <class Real> Real floor(const Real a): Rounds the input real number down to the nearest integer.template <class Real> Real ceil(const Real a): Rounds the input real number up to the nearest integer.template <class Real> bool isinf(const Real a): Returns true if the input is infinite.template <class Real> bool isnan(const Real a): Returns true if the input is NaN.
Trigonometric Functions:
template <class Real> Real sin(const Real a): Computes the sine of the input angle.template <class Real> Real cos(const Real a): Computes the cosine of the input angle.template <class Real> Real tan(const Real a): Computes the tangent of the input angle.template <class Real> Real asin(const Real a): Computes the arcsine of the input value.template <class Real> Real acos(const Real a): Computes the arccosine of the input value.template <class Real> Real atan(const Real a): Computes the arctangent of the input value.template <class Real> Real atan2(const Real a, const Real b): Computes the arctangent of the ratio of two input values.
Exponential Functions:
template <class Real> Real exp(const Real a): Computes the exponential function of the input value.template <class Real> Real log(const Real a): Computes the natural logarithm of the input value.template <class Real> Real log2(const Real a): Computes the base-2 logarithm of the input value.
Power Functions:
template <class Real> Real sqrt(const Real a): Computes the square root of the input real number.template <class Real> Real hypot(const Real a, const Real b): Computessqrt(a*a + b*b)without overflow.template <class Real, class ExpType> Real pow(const Real b, const ExpType e): Computes the power of a base raised to an exponent.template <Long e, class ValueType> constexpr ValueType pow(ValueType b): Computes the power of a base raised to a compile-time constant exponent.
#ifndef _SCTL_MATH_UTILS_HPP_
#define _SCTL_MATH_UTILS_HPP_
#include <istream> // for istream
#include <ostream> // for ostream
#include <cmath> // for acos, asin, atan, atan2, ceil, cos, exp
#include "sctl/common.hpp" // for Integer, Long, sctl
namespace sctl {
/**
* Returns the number of significant bits in the representation of the template type.
*
* @tparam Real The template type.
* @return constexpr Integer The number of significant bits.
*/
template <class Real> [[nodiscard]] inline constexpr Integer significant_bits();
/**
* Returns the machine epsilon (the difference between 1 and the smallest value greater than 1 that is representable).
*
* @tparam Real The template type.
* @return constexpr Real The machine epsilon.
*/
template <class Real> [[nodiscard]] inline constexpr Real machine_eps();
/**
* Converts a string to a real number.
*
* @tparam Real The template type.
* @param str The input string.
* @return Real The real number parsed from the string.
*/
template <class Real> [[nodiscard]] Real atoreal(const char* str);
/**
* Returns the mathematical constant pi.
*
* @tparam Real The template type.
* @return constexpr Real The value of pi.
*/
template <class Real> [[nodiscard]] inline constexpr Real const_pi() { return (Real)14488038916154245684ull/(Real)(1ull<<62) + (Real)7089564414062235240ull/(Real)(1ull<<62)/(Real)(1ull<<63); }
/**
* Returns the mathematical constant e.
*
* @tparam Real The template type.
* @return constexpr Real The value of e.
*/
template <class Real> [[nodiscard]] inline constexpr Real const_e() { return (Real)12535862302449814170ull/(Real)(1ull<<62) + (Real)6336049073805500024ull/(Real)(1ull<<62)/(Real)(1ull<<63); }
/**
* Returns the natural logarithm of 2.
*
* @tparam Real The template type.
* @return constexpr Real The value of ln(2).
*/
template <class Real> [[nodiscard]] inline constexpr Real const_ln2() { return (Real)6393154322601327829ull/(Real)(1ull<<63) + (Real)8248603190132260267ull/(Real)(1ull<<63)/(Real)(1ull<<63); }
template <class Real> [[nodiscard]] inline bool isinf(const Real a) { return std::isinf(a); }
template <class Real> [[nodiscard]] inline bool isnan(const Real a) { return std::isnan(a); }
/**
* Returns the absolute value of the input.
*
* @tparam Real The template type.
* @param a The input value.
* @return Real The absolute value of the input.
*/
template <class Real> [[nodiscard]] inline Real fabs(const Real a) { return (Real)std::fabs(a); }
/**
* Truncates the input real number to the nearest integer towards zero.
*
* @tparam Real The template type.
* @param a The input real number.
* @return Real The truncated real number.
*/
template <class Real> [[nodiscard]] inline Real trunc(const Real a) { return (Real)std::trunc(a); }
/**
* Rounds the input real number to the nearest integer.
*
* @tparam Real The template type.
* @param a The input real number.
* @return Real The rounded real number.
*/
template <class Real> [[nodiscard]] inline Real round(const Real a) { return (Real)std::round(a); }
/**
* Rounds the input real number down to the nearest integer.
*
* @tparam Real The template type.
* @param a The input real number.
* @return Real The floor of the real number.
*/
template <class Real> [[nodiscard]] inline Real floor(const Real a) { return (Real)std::floor(a); }
/**
* Rounds the input real number up to the nearest integer.
*
* @tparam Real The template type.
* @param a The input real number.
* @return Real The ceil of the real number.
*/
template <class Real> [[nodiscard]] inline Real ceil(const Real a) { return (Real)std::ceil(a); }
/**
* Computes the square root of the input real number.
*
* @tparam Real The template type.
* @param a The input real number.
* @return Real The square root of the real number.
*/
template <class Real> [[nodiscard]] inline Real sqrt(const Real a) { return (Real)std::sqrt(a); }
/**
* Computes `sqrt(a*a + b*b)` without intermediate overflow or underflow.
*
* @tparam Real The template type.
* @param a First leg.
* @param b Second leg.
* @return Real The Euclidean norm of (a, b).
*/
template <class Real> [[nodiscard]] inline Real hypot(const Real a, const Real b) { return (Real)std::hypot(a, b); }
/**
* Computes the sine of the input angle.
*
* @tparam Real The template type.
* @param a The input angle in radians.
* @return Real The sine of the angle.
*/
template <class Real> [[nodiscard]] inline Real sin(const Real a) { return (Real)std::sin(a); }
/**
* Computes the cosine of the input angle.
*
* @tparam Real The template type.
* @param a The input angle in radians.
* @return Real The cosine of the angle.
*/
template <class Real> [[nodiscard]] inline Real cos(const Real a) { return (Real)std::cos(a); }
/**
* Computes the tangent of the input angle.
*
* @tparam Real The template type.
* @param a The input angle in radians.
* @return Real The tangent of the angle.
*/
template <class Real> [[nodiscard]] inline Real tan(const Real a) { return (Real)std::tan(a); }
/**
* Computes the arcsine of the input value.
*
* @tparam Real The template type.
* @param a The input value.
* @return Real The arcsine in radians.
*/
template <class Real> [[nodiscard]] inline Real asin(const Real a) { return (Real)std::asin(a); }
/**
* Computes the arccosine of the input value.
*
* @tparam Real The template type.
* @param a The input value.
* @return Real The arccosine in radians.
*/
template <class Real> [[nodiscard]] inline Real acos(const Real a) { return (Real)std::acos(a); }
/**
* Computes the arctangent of the input value.
*
* @tparam Real The template type.
* @param a The input value.
* @return Real The arctangent in radians.
*/
template <class Real> [[nodiscard]] inline Real atan(const Real a) { return (Real)std::atan(a); }
/**
* Computes the arctangent of the ratio of two input values.
*
* @tparam Real The template type.
* @param a The numerator.
* @param b The denominator.
* @return Real The arctangent in radians.
*/
template <class Real> [[nodiscard]] inline Real atan2(const Real a, const Real b) { return (Real)std::atan2(a, b); }
/**
* Computes the remainder of the division of two input values.
*
* @tparam Real The template type.
* @param a The dividend.
* @param b The divisor.
* @return Real The remainder.
*/
template <class Real> [[nodiscard]] inline Real fmod(const Real a, const Real b) { return (Real)std::fmod(a, b); }
/**
* Computes the exponential function of the input value.
*
* @tparam Real The template type.
* @param a The input value.
* @return Real The exponential value.
*/
template <class Real> [[nodiscard]] inline Real exp(const Real a) { return (Real)std::exp(a); }
/**
* Computes the natural logarithm of the input value.
*
* @tparam Real The template type.
* @param a The input value.
* @return Real The natural logarithm.
*/
template <class Real> [[nodiscard]] inline Real log(const Real a) { return (Real)std::log(a); }
/**
* Computes the base-2 logarithm of the input value.
*
* @tparam Real The template type.
* @param a The input value.
* @return Real The base-2 logarithm.
*/
template <class Real> [[nodiscard]] inline Real log2(const Real a) { return (Real)std::log2(a); }
/**
* Computes the power of a base raised to an exponent.
*
* @tparam Real The template type of the base.
* @tparam ExpType The template type of the exponent.
* @param b The base.
* @param e The exponent.
* @return Real The result of the operation.
*/
template <class Real, class ExpType> [[nodiscard]] inline Real pow(const Real b, const ExpType e);
/**
* Computes the power of a base raised to a compile-time constant exponent.
*
* @tparam e The compile-time constant exponent.
* @tparam ValueType The template type of the base.
* @param b The base.
* @return constexpr ValueType The result of the operation.
*/
template <Long e, class ValueType> [[nodiscard]] inline constexpr ValueType pow(ValueType b);
#ifdef SCTL_QUAD_T
/**
* Class representing a quadruple precision floating-point number. To enable, the macro
* `SCTL_QUAD_T` must be defined and set equal to the compiler supported quad-precision floating
* point type (e.g. with GCC use the compiler flag: `-DSCTL_QUAD_T=__float128`).
*/
class QuadReal {
typedef SCTL_QUAD_T QuadRealType;
public:
/**
* Default constructor.
*/
QuadReal() = default;
/**
* Copy constructor.
*
* @param v The value to copy.
*/
constexpr QuadReal(const QuadReal& v) = default;
/**
* Copy assignment operator.
*
* @param The value to copy.
* @return QuadReal& The reference to the copied object.
*/
QuadReal& operator=(const QuadReal&) = default;
/**
* Destructor.
*/
~QuadReal() = default;
/**
* Constructor with explicit conversion from another type.
*
* @tparam ValueType The template type of the value.
* @param v The value to convert.
*/
template <class ValueType> constexpr QuadReal(ValueType v) : val((QuadRealType)v) {}
/**
* Explicit conversion operator to another type.
*
* @tparam ValueType The template type of the value.
* @return constexpr ValueType The converted value.
*/
template <class ValueType> explicit constexpr operator ValueType() const { return (ValueType)val; }
/**
* Addition assignment operator.
*
* @param x The value to add.
* @return QuadReal& The reference to the modified object.
*/
QuadReal& operator+=(const QuadReal& x) { val += x.val; return *this; }
/**
* Subtraction assignment operator.
*
* @param x The value to subtract.
* @return QuadReal& The reference to the modified object.
*/
QuadReal& operator-=(const QuadReal& x) { val -= x.val; return *this; }
/**
* Multiplication assignment operator.
*
* @param x The value to multiply by.
* @return QuadReal& The reference to the modified object.
*/
QuadReal& operator*=(const QuadReal& x) { val *= x.val; return *this; }
/**
* Division assignment operator.
*
* @param x The value to divide by.
* @return QuadReal& The reference to the modified object.
*/
QuadReal& operator/=(const QuadReal& x) { val /= x.val; return *this; }
/**
* Addition operator.
*
* @param x The value to add.
* @return constexpr QuadReal The result of the addition.
*/
constexpr QuadReal operator+(const QuadReal& x) const { return QuadReal(val + x.val); }
/**
* Subtraction operator.
*
* @param x The value to subtract.
* @return constexpr QuadReal The result of the subtraction.
*/
constexpr QuadReal operator-(const QuadReal& x) const { return QuadReal(val - x.val); }
/**
* Multiplication operator.
*
* @param x The value to multiply by.
* @return constexpr QuadReal The result of the multiplication.
*/
constexpr QuadReal operator*(const QuadReal& x) const { return QuadReal(val * x.val); }
/**
* Division operator.
*
* @param x The value to divide by.
* @return constexpr QuadReal The result of the division.
*/
constexpr QuadReal operator/(const QuadReal& x) const { return QuadReal(val / x.val); }
/**
* Unary negation operator.
*
* @return constexpr QuadReal The negated value.
*/
constexpr QuadReal operator-() const { return QuadReal(-val); }
/**
* Less than comparison operator.
*
* @param x The value to compare with.
* @return constexpr bool True if less than, otherwise false.
*/
constexpr bool operator< (const QuadReal& x) const { return val < x.val; }
/**
* Greater than comparison operator.
*
* @param x The value to compare with.
* @return constexpr bool True if greater than, otherwise false.
*/
constexpr bool operator> (const QuadReal& x) const { return val > x.val; }
/**
* Not equal comparison operator.
*
* @param x The value to compare with.
* @return constexpr bool True if not equal, otherwise false.
*/
constexpr bool operator!=(const QuadReal& x) const { return val != x.val; }
/**
* Equal comparison operator.
*
* @param x The value to compare with.
* @return constexpr bool True if equal, otherwise false.
*/
constexpr bool operator==(const QuadReal& x) const { return val == x.val; }
/**
* Less than or equal comparison operator.
*
* @param x The value to compare with.
* @return constexpr bool True if less than or equal, otherwise false.
*/
constexpr bool operator<=(const QuadReal& x) const { return val <= x.val; }
/**
* Greater than or equal comparison operator.
*
* @param x The value to compare with.
* @return constexpr bool True if greater than or equal, otherwise false.
*/
constexpr bool operator>=(const QuadReal& x) const { return val >= x.val; }
/**
* Friend addition operator for QuadRealType and QuadReal.
*
* @param a The value to add.
* @param b The value to add.
* @return constexpr QuadReal The result of the addition.
*/
constexpr friend QuadReal operator+(const QuadRealType& a, const QuadReal& b) { return QuadReal(a) + b; }
/**
* Friend subtraction operator for QuadRealType and QuadReal.
*
* @param a The value to subtract.
* @param b The value to subtract.
* @return constexpr QuadReal The result of the subtraction.
*/
constexpr friend QuadReal operator-(const QuadRealType& a, const QuadReal& b) { return QuadReal(a) - b; }
/**
* Friend multiplication operator for QuadRealType and QuadReal.
*
* @param a The value to multiply by.
* @param b The value to multiply.
* @return constexpr QuadReal The result of the multiplication.
*/
constexpr friend QuadReal operator*(const QuadRealType& a, const QuadReal& b) { return QuadReal(a) * b; }
/**
* Friend division operator for QuadRealType and QuadReal.
*
* @param a The value to divide by.
* @param b The value to divide.
* @return constexpr QuadReal The result of the division.
*/
constexpr friend QuadReal operator/(const QuadRealType& a, const QuadReal& b) { return QuadReal(a) / b; }
/**
* Friend less than comparison operator for QuadRealType and QuadReal.
*
* @param a The value to compare with.
* @param b The value to compare.
* @return constexpr bool True if less than, otherwise false.
*/
constexpr friend bool operator< (const QuadRealType& a, const QuadReal& b) { return QuadReal(a) < b; }
/**
* Friend greater than comparison operator for QuadRealType and QuadReal.
*
* @param a The value to compare with.
* @param b The value to compare.
* @return constexpr bool True if greater than, otherwise false.
*/
constexpr friend bool operator> (const QuadRealType& a, const QuadReal& b) { return QuadReal(a) > b; }
/**
* Friend not equal comparison operator for QuadRealType and QuadReal.
*
* @param a The value to compare with.
* @param b The value to compare.
* @return constexpr bool True if not equal, otherwise false.
*/
constexpr friend bool operator!=(const QuadRealType& a, const QuadReal& b) { return QuadReal(a) != b; }
/**
* Friend equal comparison operator for QuadRealType and QuadReal.
*
* @param a The value to compare with.
* @param b The value to compare.
* @return constexpr bool True if equal, otherwise false.
*/
constexpr friend bool operator==(const QuadRealType& a, const QuadReal& b) { return QuadReal(a) == b; }
/**
* Friend less than or equal comparison operator for QuadRealType and QuadReal.
*
* @param a The value to compare with.
* @param b The value to compare.
* @return constexpr bool True if less than or equal, otherwise false.
*/
constexpr friend bool operator<=(const QuadRealType& a, const QuadReal& b) { return QuadReal(a) <= b; }
/**
* Friend greater than or equal comparison operator for QuadRealType and QuadReal.
*
* @param a The value to compare with.
* @param b The value to compare.
* @return constexpr bool True if greater than or equal, otherwise false.
*/
constexpr friend bool operator>=(const QuadRealType& a, const QuadReal& b) { return QuadReal(a) >= b; }
/**
* Friend function for truncating a QuadReal.
*
* @param x The QuadReal to truncate.
* @return QuadReal The truncated QuadReal.
*/
friend QuadReal trunc<QuadReal>(const QuadReal);
private:
QuadRealType val; ///< The value of the QuadReal.
};
/**
* Overloads the output stream operator for QuadReal objects.
*
* @param output The output stream.
* @param x The QuadReal object to be output.
* @return std::ostream& The modified output stream.
*/
inline std::ostream& operator<<(std::ostream& output, const QuadReal& x);
/**
* Overloads the input stream operator for QuadReal objects.
*
* @param inputstream The input stream.
* @param x The QuadReal object to store the input.
* @return std::istream& The modified input stream.
*/
inline std::istream& operator>>(std::istream& inputstream, QuadReal& x);
#endif
} // end namespace
#endif // _SCTL_MATH_UTILS_HPP_