mirror of
https://github.com/holub/mame
synced 2025-10-04 00:23:43 +03:00

- more const - explicitly raise exceptions instead of leaving this to log.fatal() - correct a number of cppcheck findings. - dead code removal - clang lint corrections, e.g. include order
338 lines
7.5 KiB
C++
338 lines
7.5 KiB
C++
// license:GPL-2.0+
|
|
// copyright-holders:Couriersud
|
|
/*
|
|
* pmath.h
|
|
*
|
|
*/
|
|
|
|
#ifndef PMATH_H_
|
|
#define PMATH_H_
|
|
|
|
#include "pconfig.h"
|
|
|
|
#include <algorithm>
|
|
#include <cmath>
|
|
#include <type_traits>
|
|
|
|
#if (PUSE_FLOAT128)
|
|
#include <quadmath.h>
|
|
#endif
|
|
|
|
namespace plib
|
|
{
|
|
|
|
/*! Holds constants used repeatedly.
|
|
*
|
|
* @tparam T floating point type
|
|
*
|
|
* Using the structure members we can avoid magic numbers in the code.
|
|
* In addition, this is a typesafe approach.
|
|
*/
|
|
template <typename T>
|
|
struct constants
|
|
{
|
|
static inline constexpr T zero() noexcept { return static_cast<T>(0); }
|
|
static inline constexpr T half() noexcept { return static_cast<T>(0.5); }
|
|
static inline constexpr T one() noexcept { return static_cast<T>(1); }
|
|
static inline constexpr T two() noexcept { return static_cast<T>(2); }
|
|
static inline constexpr T three() noexcept { return static_cast<T>(3); }
|
|
static inline constexpr T four() noexcept { return static_cast<T>(4); }
|
|
static inline constexpr T sqrt2() noexcept { return static_cast<T>(1.414213562373095048801688724209L); }
|
|
static inline constexpr T pi() noexcept { return static_cast<T>(3.14159265358979323846264338327950L); }
|
|
|
|
/*!
|
|
* \brief Electric constant of vacuum
|
|
*/
|
|
static inline constexpr T eps_0() noexcept { return static_cast<T>(8.854187817e-12); }
|
|
/*!
|
|
* \brief Relative permittivity of Silicon dioxide
|
|
*/
|
|
static inline constexpr T eps_SiO2() noexcept { return static_cast<T>(3.9); }
|
|
/*!
|
|
* \brief Relative permittivity of Silicon
|
|
*/
|
|
static inline constexpr T eps_Si() noexcept { return static_cast<T>(11.7); }
|
|
/*!
|
|
* \brief Boltzmann constant
|
|
*/
|
|
static inline constexpr T k_b() noexcept { return static_cast<T>(1.38064852e-23); }
|
|
/*!
|
|
* \brief room temperature (gives VT = 0.02585 at T=300)
|
|
*/
|
|
static inline constexpr T T0() noexcept { return static_cast<T>(300); }
|
|
/*!
|
|
* \brief Elementary charge
|
|
*/
|
|
static inline constexpr T Q_e() noexcept { return static_cast<T>(1.6021765314e-19); }
|
|
/*!
|
|
* \brief Intrinsic carrier concentration in 1/m^3 of Silicon
|
|
*/
|
|
static inline constexpr T NiSi() noexcept { return static_cast<T>(1.45e16); }
|
|
/*!
|
|
* \brief clearly identify magic numbers in code
|
|
*
|
|
* Magic numbers should be avoided. The magic member at least clearly
|
|
* identifies them and makes it easier to convert them to named constants
|
|
* later.
|
|
*/
|
|
template <typename V>
|
|
static inline constexpr const T magic(V &&v) noexcept { return static_cast<T>(v); }
|
|
};
|
|
|
|
/*! typesafe reciprocal function
|
|
*
|
|
* @tparam T type of the argument
|
|
* @param v argument
|
|
* @return reciprocal of argument
|
|
*/
|
|
template <typename T>
|
|
static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
|
|
reciprocal(T v) noexcept
|
|
{
|
|
return constants<T>::one() / v;
|
|
}
|
|
|
|
/*! abs function
|
|
*
|
|
* @tparam T type of the argument
|
|
* @param v argument
|
|
* @return absolute value of argument
|
|
*/
|
|
template <typename T>
|
|
static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
|
|
abs(T v) noexcept
|
|
{
|
|
return std::abs(v);
|
|
}
|
|
|
|
/*! sqrt function
|
|
*
|
|
* @tparam T type of the argument
|
|
* @param v argument
|
|
* @return absolute value of argument
|
|
*/
|
|
template <typename T>
|
|
static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
|
|
sqrt(T v) noexcept
|
|
{
|
|
return std::sqrt(v);
|
|
}
|
|
|
|
/*! hypot function
|
|
*
|
|
* @tparam T type of the arguments
|
|
* @param v1 first argument
|
|
* @param v2 second argument
|
|
* @return sqrt(v1*v1+v2*v2)
|
|
*/
|
|
template <typename T>
|
|
static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
|
|
hypot(T v1, T v2) noexcept
|
|
{
|
|
return std::hypot(v1, v2);
|
|
}
|
|
|
|
/*! exp function
|
|
*
|
|
* @tparam T type of the argument
|
|
* @param v argument
|
|
* @return exp(v)
|
|
*/
|
|
template <typename T>
|
|
static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
|
|
exp(T v) noexcept
|
|
{
|
|
return std::exp(v);
|
|
}
|
|
|
|
/*! log function
|
|
*
|
|
* @tparam T type of the argument
|
|
* @param v argument
|
|
* @return log(v)
|
|
*/
|
|
template <typename T>
|
|
static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
|
|
log(T v) noexcept
|
|
{
|
|
return std::log(v);
|
|
}
|
|
|
|
/*! tanh function
|
|
*
|
|
* @tparam T type of the argument
|
|
* @param v argument
|
|
* @return tanh(v)
|
|
*/
|
|
template <typename T>
|
|
static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
|
|
tanh(T v) noexcept
|
|
{
|
|
return std::tanh(v);
|
|
}
|
|
|
|
/*! floor function
|
|
*
|
|
* @tparam T type of the argument
|
|
* @param v argument
|
|
* @return floor(v)
|
|
*/
|
|
template <typename T>
|
|
static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
|
|
floor(T v) noexcept
|
|
{
|
|
return std::floor(v);
|
|
}
|
|
|
|
/*! log1p function
|
|
*
|
|
* @tparam T type of the argument
|
|
* @param v argument
|
|
* @return log(1 + v)
|
|
*/
|
|
template <typename T>
|
|
static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
|
|
log1p(T v) noexcept
|
|
{
|
|
return std::log1p(v);
|
|
}
|
|
|
|
/*! sin function
|
|
*
|
|
* @tparam T type of the argument
|
|
* @param v argument
|
|
* @return sin(v)
|
|
*/
|
|
template <typename T>
|
|
static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
|
|
sin(T v) noexcept
|
|
{
|
|
return std::sin(v);
|
|
}
|
|
|
|
/*! cos function
|
|
*
|
|
* @tparam T type of the argument
|
|
* @param v argument
|
|
* @return cos(v)
|
|
*/
|
|
template <typename T>
|
|
static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
|
|
cos(T v) noexcept
|
|
{
|
|
return std::cos(v);
|
|
}
|
|
|
|
/*! trunc function
|
|
*
|
|
* @tparam T type of the argument
|
|
* @param v argument
|
|
* @return trunc(v)
|
|
*/
|
|
template <typename T>
|
|
static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
|
|
trunc(T v) noexcept
|
|
{
|
|
return std::trunc(v);
|
|
}
|
|
|
|
/*! pow function
|
|
*
|
|
* @tparam T1 type of the first argument
|
|
* @tparam T2 type of the second argument
|
|
* @param v argument
|
|
* @param p power
|
|
* @return v^p
|
|
*
|
|
* FIXME: limited implementation
|
|
*/
|
|
template <typename T1, typename T2>
|
|
static inline T1
|
|
pow(T1 v, T2 p) noexcept
|
|
{
|
|
return std::pow(v, p);
|
|
}
|
|
|
|
#if (PUSE_FLOAT128)
|
|
static inline constexpr __float128 reciprocal(__float128 v) noexcept
|
|
{
|
|
return constants<__float128>::one() / v;
|
|
}
|
|
|
|
static inline __float128 abs(__float128 v) noexcept
|
|
{
|
|
return fabsq(v);
|
|
}
|
|
|
|
static inline __float128 sqrt(__float128 v) noexcept
|
|
{
|
|
return sqrtq(v);
|
|
}
|
|
|
|
static inline __float128 hypot(__float128 v1, __float128 v2) noexcept
|
|
{
|
|
return hypotq(v1, v2);
|
|
}
|
|
|
|
static inline __float128 exp(__float128 v) noexcept
|
|
{
|
|
return expq(v);
|
|
}
|
|
|
|
static inline __float128 log(__float128 v) noexcept
|
|
{
|
|
return logq(v);
|
|
}
|
|
|
|
static inline __float128 tanh(__float128 v) noexcept
|
|
{
|
|
return tanhq(v);
|
|
}
|
|
|
|
static inline __float128 floor(__float128 v) noexcept
|
|
{
|
|
return floorq(v);
|
|
}
|
|
|
|
static inline __float128 log1p(__float128 v) noexcept
|
|
{
|
|
return log1pq(v);
|
|
}
|
|
|
|
static inline __float128 sin(__float128 v) noexcept
|
|
{
|
|
return sinq(v);
|
|
}
|
|
|
|
static inline __float128 cos(__float128 v) noexcept
|
|
{
|
|
return cosq(v);
|
|
}
|
|
|
|
static inline __float128 trunc(__float128 v) noexcept
|
|
{
|
|
return truncq(v);
|
|
}
|
|
|
|
template <typename T>
|
|
static inline __float128 pow(__float128 v, T p) noexcept
|
|
{
|
|
return powq(v, static_cast<__float128>(p));
|
|
}
|
|
|
|
static inline __float128 pow(__float128 v, int p) noexcept
|
|
{
|
|
if (p==2)
|
|
return v*v;
|
|
else
|
|
return powq(v, static_cast<__float128>(p));
|
|
}
|
|
|
|
#endif
|
|
|
|
static_assert(noexcept(constants<double>::one()) == true, "Not evaluated as constexpr");
|
|
|
|
} // namespace plib
|
|
|
|
#endif /* PMATH_H_ */
|