Files
TheRock/base/half/web/half.hpp
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

937 lines
34 KiB
C++

// half - IEEE 754-based half-precision floating point library.
//
// Copyright (c) 2012-2017 Christian Rau <rauy@users.sourceforge.net>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// This is a dummy header file to provide a clean interface documentation to Doxygen, without any ugly internals.
/// \file
/// Main header file of the library.
/// Default rounding mode.
/// This specifies the rounding mode used for all conversions between [half](\ref half_float::half)s and `float`s as well as
/// for the half_cast() if not specifying a rounding mode explicitly. It can be redefined (before including `half.hpp`) to one
/// of the standard rounding modes using their respective constants or the equivalent values of
/// [std::float_round_style](http://en.cppreference.com/w/cpp/types/numeric_limits/float_round_style):
///
/// `std::float_round_style` | value | rounding
/// ---------------------------------|-------|-------------------------
/// `std::round_indeterminate` | -1 | fastest (default)
/// `std::round_toward_zero` | 0 | toward zero
/// `std::round_to_nearest` | 1 | to nearest
/// `std::round_toward_infinity` | 2 | toward positive infinity
/// `std::round_toward_neg_infinity` | 3 | toward negative infinity
///
/// By default this is set to `-1` (`std::round_indeterminate`), which uses truncation (round toward zero, but with overflows
/// set to infinity) and is the fastest rounding mode possible. It can even be set to
/// [std::numeric_limits<float>::round_style](http://en.cppreference.com/w/cpp/types/numeric_limits/round_style) to synchronize
/// the rounding mode with that of the underlying single-precision implementation.
#define HALF_ROUND_STYLE -1
/// Tie-breaking behaviour for round to nearest.
/// This specifies if ties in round to nearest should be resolved by rounding to the nearest even value. By default this is
/// defined to `0` resulting in the faster but slightly more biased behaviour of rounding away from zero in half-way cases (and
/// thus equal to the round() function), but can be redefined to `1` (before including half.hpp) if more IEEE-conformant
/// behaviour is needed.
#define HALF_ROUND_TIES_TO_EVEN 0
/// Value signaling overflow.
/// In correspondence with `HUGE_VAL[F|L]` from `<cmath>` this symbol expands to a positive value signaling the overflow of an
/// operation, in particular it just evaluates to positive infinity.
///
/// **See also:** Documentation for [HUGE_VAL](http://en.cppreference.com/w/cpp/numeric/math/HUGE_VAL)
#define HUGE_VALH std::numeric_limits<half_float::half>::infinity()
/// Fast half-precision fma function.
/// This symbol is only defined if the fma() function generally executes as fast as, or faster than, a separate
/// half-precision multiplication followed by an addition. Due to the internal single-precision implementation of all
/// arithmetic operations, this is in fact always the case.
///
/// **See also:** Documentation for [FP_FAST_FMA](http://en.cppreference.com/w/cpp/numeric/math/fma)
#define FP_FAST_FMAH 1
/// Main namespace for half precision functionality.
/// This namespace contains all the functionality provided by the library.
namespace half_float
{
/// Half-precision floating point type.
/// This class implements an IEEE-conformant half-precision floating point type with the usual arithmetic operators and
/// conversions. It is implicitly convertible to single-precision floating point, which makes artihmetic expressions and
/// functions with mixed-type operands to be of the most precise operand type. Additionally all arithmetic operations
/// (and many mathematical functions) are carried out in single-precision internally. All conversions from single- to
/// half-precision are done using the library's default rounding mode, but temporary results inside chained arithmetic
/// expressions are kept in single-precision as long as possible (while of course still maintaining a strong half-precision type).
///
/// According to the C++98/03 definition, the half type is not a POD type. But according to C++11's less strict and
/// extended definitions it is both a standard layout type and a trivially copyable type (even if not a POD type), which
/// means it can be standard-conformantly copied using raw binary copies. But in this context some more words about the
/// actual size of the type. Although the half is representing an IEEE 16-bit type, it does not neccessarily have to be of
/// exactly 16-bits size. But on any reasonable implementation the actual binary representation of this type will most
/// probably not ivolve any additional "magic" or padding beyond the simple binary representation of the underlying 16-bit
/// IEEE number, even if not strictly guaranteed by the standard. But even then it only has an actual size of 16 bits if
/// your C++ implementation supports an unsigned integer type of exactly 16 bits width. But this should be the case on
/// nearly any reasonable platform.
///
/// So if your C++ implementation is not totally exotic or imposes special alignment requirements, it is a reasonable
/// assumption that the data of a half is just comprised of the 2 bytes of the underlying IEEE representation.
struct half
{
/// \name Construction and assignment
/// \{
/// Default constructor.
/// This initializes the half to 0. Although this does not match the builtin types' default-initialization semantics
/// and may be less efficient than no initialization, it is needed to provide proper value-initialization semantics.
constexpr half() noexcept;
/// Conversion constructor.
/// \param rhs float to convert
explicit half(float rhs);
/// Conversion to single-precision.
/// \return single precision value
operator float() const;
/// Single-precision assignment.
/// \param rhs single-precision value to copy from
/// \return reference to this half
half& operator=(float rhs);
/// \}
/// \name Arithmetic updates
/// \{
/// Arithmetic assignment.
/// This operation uses the underlying single-precision implementation.
/// \tparam E type of concrete half expression
/// \param rhs half to add
/// \return reference to this half
half& operator+=(half rhs);
/// Arithmetic assignment.
/// This operation uses the underlying single-precision implementation.
/// \tparam E type of concrete half expression
/// \param rhs half to subtract
/// \return reference to this half
half& operator-=(half rhs);
/// Arithmetic assignment.
/// This operation uses the underlying single-precision implementation.
/// \tparam E type of concrete half expression
/// \param rhs half to multiply with
/// \return reference to this half
half& operator*=(half rhs);
/// Arithmetic assignment.
/// This operation uses the underlying single-precision implementation.
/// \tparam E type of concrete half expression
/// \param rhs half to divide by
/// \return reference to this half
half& operator/=(half rhs);
/// Arithmetic assignment.
/// This operation uses the underlying single-precision implementation.
/// \param rhs single-precision value to add
/// \return reference to this half
half& operator+=(float rhs);
/// Arithmetic assignment.
/// This operation uses the underlying single-precision implementation.
/// \param rhs single-precision value to subtract
/// \return reference to this half
half& operator-=(float rhs);
/// Arithmetic assignment.
/// This operation uses the underlying single-precision implementation.
/// \param rhs single-precision value to multiply with
/// \return reference to this half
half& operator*=(float rhs);
/// Arithmetic assignment.
/// This operation uses the underlying single-precision implementation.
/// \param rhs single-precision value to divide by
/// \return reference to this half
half& operator/=(float rhs);
/// \}
/// \name Increment and decrement
/// \{
/// Prefix increment.
/// This operation uses the underlying single-precision implementation.
/// \return incremented half value
half& operator++();
/// Prefix decrement.
/// This operation uses the underlying single-precision implementation.
/// \return decremented half value
half& operator--();
/// Postfix increment.
/// This operation uses the underlying single-precision implementation.
/// \return non-incremented half value
half operator++(int);
/// Postfix decrement.
/// This operation uses the underlying single-precision implementation.
/// \return non-decremented half value
half operator--(int);
/// \}
};
/// \name Comparison operators
/// \{
/// Comparison for equality.
/// \param a first operand
/// \param b second operand
/// \retval true if operands equal
/// \retval false else
bool operator==(half a, half b);
/// Comparison for inequality.
/// \param a first operand
/// \param b second operand
/// \retval true if operands not equal
/// \retval false else
bool operator!=(half a, half b);
/// Comparison for less than.
/// \param a first operand
/// \param b second operand
/// \retval true if \a a less than \a b
/// \retval false else
bool operator<(half a, half b);
/// Comparison for greater than.
/// \param a first operand
/// \param b second operand
/// \retval true if \a a greater than \a b
/// \retval false else
bool operator>(half a, half b);
/// Comparison for less equal.
/// \param a first operand
/// \param b second operand
/// \retval true if \a a less equal \a b
/// \retval false else
bool operator<=(half a, half b);
/// Comparison for greater equal.
/// \param a first operand
/// \param b second operand
/// \retval true if \a a greater equal \a b
/// \retval false else
bool operator>=(half a, half b);
/// \}
/// \name Arithmetic operators
/// \{
/// Add halfs.
/// This operation uses the underlying single-precision implementation.
/// \param a left operand
/// \param b right operand
/// \return sum of halfs
half operator+(half a, half b);
/// Subtract halfs.
/// This operation uses the underlying single-precision implementation.
/// \param a left operand
/// \param b right operand
/// \return difference of halfs
half operator-(half a, half b);
/// Multiply halfs.
/// This operation uses the underlying single-precision implementation.
/// \param a left operand
/// \param b right operand
/// \return product of halfs
half operator*(half a, half b);
/// Divide halfs.
/// This operation uses the underlying single-precision implementation.
/// \param a left operand
/// \param b right operand
/// \return quotient of halfs
half operator/(half a, half b);
/// Identity.
/// \param h operand
/// \return uncahnged operand
half constexpr operator+(half h);
/// Negation.
/// \param h operand
/// \return negated operand
half constexpr operator-(half h);
/// \}
/// \name Input and output
/// \{
/// Output operator.
/// \tparam charT character type
/// \tparam traits character traits
/// \param out output stream to write into
/// \param h half to write
/// \return reference to output stream
template<typename charT,typename traits> std::basic_ostream<charT,traits>& operator<<(std::basic_ostream<charT,traits> &out, half h);
/// Input operator.
/// \tparam charT character type
/// \tparam traits character traits
/// \param in input stream to read from
/// \param h half to read into
/// \return reference to input stream
template<typename charT,typename traits> std::basic_istream<charT,traits>& operator>>(std::basic_istream<charT,traits> &in, half &h);
/// \}
/// \name Basic mathematical operations
/// \{
/// Absolute value.
/// \param arg operand
/// \return absolute value of \a arg
half abs(half arg);
/// Absolute value.
/// \param arg operand
/// \return absolute value of \a arg
half fabs(half arg);
/// Remainder of division.
/// This function uses the underlying single-precision implementation.
/// \param x first operand
/// \param y second operand
/// \return remainder of floating point division.
half fmod(half x, half y);
/// Remainder of division.
/// This function uses the underlying single-precision implementation if C++11 `<cmath>` functions are supported.
/// \param x first operand
/// \param y second operand
/// \return remainder of floating point division.
half remainder(half x, half y);
/// Remainder of division.
/// This function uses the underlying single-precision implementation if C++11 `<cmath>` functions are supported.
/// \param x first operand
/// \param y second operand
/// \param quo address to store some bits of quotient at
/// \return remainder of floating point division.
half remquo(half x, half y, int *quo);
/// Fused multiply add.
/// This function uses the underlying single-precision implementation from C++11 `<cmath>` if it is supported **and**
/// faster than the straight-forward single-precision implementation (thus if `FP_FAST_FMAF` is defined).
/// \param x first operand
/// \param y second operand
/// \param z third operand
/// \return ( \a x * \a y ) + \a z rounded as one operation.
half fma(half x, half y, half z);
/// Minimum of halfs.
/// \param x first operand
/// \param y second operand
/// \return minimum of operands
half fmin(half x, half y);
/// Maximum of halfs.
/// \param x first operand
/// \param y second operand
/// \return maximum of operands
half fmax(half x, half y);
/// Positive difference.
/// This function uses the underlying single-precision implementation if C++11 `<cmath>` functions are supported.
/// \param x first operand
/// \param y second operand
/// \return \a x - \a y or 0 if difference negative
half fdim(half x, half y);
/// Get NaN value.
/// \return quiet NaN
half nanh(const char*);
/// \}
/// \name Exponential functions
/// \{
/// Exponential function.
/// This function uses the underlying single-precision implementation.
/// \param arg function argument
/// \return e raised to \a arg
half exp(half arg);
/// Binary exponential.
/// This function uses the underlying single-precision implementation if C++11 `<cmath>` functions are supported.
/// \param arg function argument
/// \return 2 raised to \a arg
half exp2(half arg);
/// Exponential minus one.
/// This function uses the underlying single-precision implementation if C++11 `<cmath>` functions are supported.
/// \param arg function argument
/// \return e raised to \a arg and subtracted by 1
half expm1(half arg);
/// Natural logorithm.
/// This function uses the underlying single-precision implementation.
/// \param arg function argument
/// \return logarithm of \a arg to base e
half log(half arg);
/// Common logorithm.
/// This function uses the underlying single-precision implementation.
/// \param arg function argument
/// \return logarithm of \a arg to base 10
half log10(half arg);
/// Natural logorithm.
/// This function uses the underlying single-precision implementation if C++11 `<cmath>` functions are supported.
/// \param arg function argument
/// \return logarithm of \a arg + 1 to base e
half log1p(half arg);
/// Binary logorithm.
/// This function uses the underlying single-precision implementation if C++11 `<cmath>` functions are supported.
/// \param arg function argument
/// \return logarithm of \a arg to base 2
half log2(half arg);
/// \}
/// \name Power functions
/// \{
/// Square root.
/// This function uses the underlying single-precision implementation.
/// \param arg function argument
/// \return square root of \a arg
half sqrt(half arg);
/// Cubic root.
/// This function uses the underlying single-precision implementation if C++11 `<cmath>` functions are supported.
/// \param arg function argument
/// \return cubic root of \a arg
half cbrt(half arg);
/// Hypotenuse function.
/// This function uses the underlying single-precision implementation if C++11 `<cmath>` functions are supported.
/// \param x first argument
/// \param y second argument
/// \return square root of sum of squares without internal over- or underflows
half hypot(half x, half y);
/// Power function.
/// This function uses the underlying single-precision implementation.
/// \param base first argument
/// \param exp second argument
/// \return \a base raised to \a exp
half pow(half base, half exp);
/// \}
/// \name Trigonometric functions
/// \{
/// Sine function.
/// This function uses the underlying single-precision implementation.
/// \param arg function argument
/// \return sine value of \a arg
half sin(half arg);
/// Cosine function.
/// This function uses the underlying single-precision implementation.
/// \param arg function argument
/// \return cosine value of \a arg
half cos(half arg);
/// Tangent function.
/// This function uses the underlying single-precision implementation.
/// \param arg function argument
/// \return tangent value of \a arg
half tan(half arg);
/// Arc sine.
/// This function uses the underlying single-precision implementation.
/// \param arg function argument
/// \return arc sine value of \a arg
half asin(half arg);
/// Arc cosine function.
/// This function uses the underlying single-precision implementation.
/// \param arg function argument
/// \return arc cosine value of \a arg
half acos(half arg);
/// Arc tangent function.
/// This function uses the underlying single-precision implementation.
/// \param arg function argument
/// \return arc tangent value of \a arg
half atan(half arg);
/// Arc tangent function.
/// This function uses the underlying single-precision implementation.
/// \param x first argument
/// \param y second argument
/// \return arc tangent value
half atan2(half x, half y);
/// \}
/// \name Hyperbolic functions
/// \{
/// Hyperbolic sine.
/// This function uses the underlying single-precision implementation.
/// \param arg function argument
/// \return hyperbolic sine value of \a arg
half sinh(half arg);
/// Hyperbolic cosine.
/// This function uses the underlying single-precision implementation.
/// \param arg function argument
/// \return hyperbolic cosine value of \a arg
half cosh(half arg);
/// Hyperbolic tangent.
/// This function uses the underlying single-precision implementation.
/// \param arg function argument
/// \return hyperbolic tangent value of \a arg
half tanh(half arg);
/// Hyperbolic area sine.
/// This function uses the underlying single-precision implementation if C++11 `<cmath>` functions are supported.
/// \param arg function argument
/// \return hyperbolic area sine value of \a arg
half asinh(half arg);
/// Hyperbolic area cosine.
/// This function uses the underlying single-precision implementation if C++11 `<cmath>` functions are supported.
/// \param arg function argument
/// \return hyperbolic area cosine value of \a arg
half acosh(half arg);
/// Hyperbolic area tangent.
/// This function uses the underlying single-precision implementation if C++11 `<cmath>` functions are supported.
/// \param arg function argument
/// \return hyperbolic area tangent value of \a arg
half atanh(half arg);
/// \}
/// \name Error and gamma functions
/// \{
/// Error function.
/// This function uses the underlying single-precision implementation if C++11 `<cmath>` functions are supported.
/// \param arg function argument
/// \return error function value of \a arg
half erf(half arg);
/// Complementary error function.
/// This function uses the underlying single-precision implementation if C++11 `<cmath>` functions are supported.
/// \param arg function argument
/// \return 1 minus error function value of \a arg
half erfc(half arg);
/// Natural logarithm of gamma function.
/// This function uses the underlying single-precision implementation if C++11 `<cmath>` functions are supported.
/// \param arg function argument
/// \return natural logarith of gamma function for \a arg
half lgamma(half arg);
/// Gamma function.
/// This function uses the underlying single-precision implementation if C++11 `<cmath>` functions are supported.
/// \param arg function argument
/// \return gamma function value of \a arg
half tgamma(half arg);
/// \}
/// \name Rounding
/// \{
/// Nearest integer not less than half value.
/// \param arg half to round
/// \return nearest integer not less than \a arg
half ceil(half arg);
/// Nearest integer not greater than half value.
/// \param arg half to round
/// \return nearest integer not greater than \a arg
half floor(half arg);
/// Nearest integer not greater in magnitude than half value.
/// \param arg half to round
/// \return nearest integer not greater in magnitude than \a arg
half trunc(half arg);
/// Nearest integer.
/// \param arg half to round
/// \return nearest integer, rounded away from zero in half-way cases
half round(half arg);
/// Nearest integer.
/// \param arg half to round
/// \return nearest integer, rounded away from zero in half-way cases
long lround(half arg);
/// Nearest integer.
/// This function requires support for C++11 `long long`.
/// \param arg half to round
/// \return nearest integer, rounded away from zero in half-way cases
long long llround(half arg);
/// Nearest integer.
/// \tparam E type of half expression
/// \param arg half expression to round
/// \return nearest integer using default rounding mode
half nearbyint(half arg);
/// Nearest integer.
/// \tparam E type of half expression
/// \param arg half expression to round
/// \return nearest integer using default rounding mode
half rint(half arg);
/// Nearest integer.
/// \tparam E type of half expression
/// \param arg half expression to round
/// \return nearest integer using default rounding mode
long lrint(half arg);
/// Nearest integer.
/// This function requires support for C++11 `long long`.
/// \tparam E type of half expression
/// \param arg half expression to round
/// \return nearest integer using default rounding mode
long long llrint(half arg);
/// \}
/// \name Floating point manipulation
/// \{
/// Decompress floating point number.
/// \param arg number to decompress
/// \param exp address to store exponent at
/// \return significant in range [0.5, 1)
half frexp(half arg, int *exp);
/// Multiply by power of two.
/// \param arg number to modify
/// \param exp power of two to multiply with
/// \return \a arg multplied by 2 raised to \a exp
half ldexp(half arg, int exp);
/// Extract integer and fractional parts.
/// \param x number to decompress
/// \param iptr address to store integer part at
/// \return fractional part
half modf(half x, half *iptr);
/// Multiply by power of two.
/// \param x number to modify
/// \param exp power of two to multiply with
/// \return \a arg multplied by 2 raised to \a exp
half scalbn(half x, int exp);
/// Multiply by power of two.
/// \param x number to modify
/// \param exp power of two to multiply with
/// \return \a arg multplied by 2 raised to \a exp
half scalbln(half x, long exp);
/// Extract exponent.
/// \param arg number to query
/// \return floating point exponent
/// \retval FP_ILOGB0 for zero
/// \retval FP_ILOGBNAN for NaN
/// \retval MAX_INT for infinity
int ilogb(half arg);
/// Extract exponent.
/// \param arg number to query
/// \return floating point exponent
half logb(half arg);
/// Next representable value.
/// \param from value to compute next representable value for
/// \param to direction towards which to compute next value
/// \return next representable value after \a from in direction towards \a to
half nextafter(half from, half to);
/// Next representable value.
/// \param from value to compute next representable value for
/// \param to direction towards which to compute next value
/// \return next representable value after \a from in direction towards \a to
half nexttoward(half from, long double to);
/// Take sign.
/// \param x value to change sign for
/// \param y value to take sign from
/// \return value equal to \a x in magnitude and to \a y in sign
half copysign(half x, half y);
/// \}
/// \name Floating point classification
/// \{
/// Classify floating point value.
/// \param arg number to classify
/// \retval FP_ZERO for positive and negative zero
/// \retval FP_SUBNORMAL for subnormal numbers
/// \retval FP_INFINITY for positive and negative infinity
/// \retval FP_NAN for NaNs
/// \retval FP_NORMAL for all other (normal) values
int fpclassify(half arg);
/// Check if finite number.
/// \param arg number to check
/// \retval true if neither infinity nor NaN
/// \retval false else
bool isfinite(half arg);
/// Check for infinity.
/// \param arg number to check
/// \retval true for positive or negative infinity
/// \retval false else
bool isinf(half arg);
/// Check for NaN.
/// \param arg number to check
/// \retval true for NaNs
/// \retval false else
bool isnan(half arg);
/// Check if normal number.
/// \param arg number to check
/// \retval true if normal number
/// \retval false if either subnormal, zero, infinity or NaN
bool isnormal(half arg);
/// Check sign.
/// \param arg number to check
/// \retval true for negative number
/// \retval false for positive number
bool signbit(half arg);
/// \}
/// \name Comparison
/// \{
/// Comparison for greater than.
/// \param x first operand
/// \param y second operand
/// \retval true if \a x greater than \a y
/// \retval false else
bool isgreater(half x, half y);
/// Comparison for greater equal.
/// \param x first operand
/// \param y second operand
/// \retval true if \a x greater equal \a y
/// \retval false else
bool isgreaterequal(half x, half y);
/// Comparison for less than.
/// \param x first operand
/// \param y second operand
/// \retval true if \a x less than \a y
/// \retval false else
bool isless(half x, half y);
/// Comparison for less equal.
/// \param x first operand
/// \param y second operand
/// \retval true if \a x less equal \a y
/// \retval false else
bool islessequal(half x, half y);
/// Comarison for less or greater.
/// \param x first operand
/// \param y second operand
/// \retval true if either less or greater
/// \retval false else
bool islessgreater(half x, half y);
/// Check if unordered.
/// \param x first operand
/// \param y second operand
/// \retval true if unordered (one or two NaN operands)
/// \retval false else
bool isunordered(half x, half y);
/// \}
/// \name Casting
/// \{
/// Cast to or from half-precision floating point number.
/// This casts between [half](\ref half_float::half) and any built-in arithmetic type. The values are converted directly
/// using the given rounding mode, without any roundtrip over `float` that a `static_cast` would otherwise do. It uses the
/// default rounding mode.
///
/// Using this cast with neither of the two types being a [half](\ref half_float::half) or with any of the two types
/// not being a built-in arithmetic type (apart from [half](\ref half_float::half), of course) results in a compiler
/// error and casting between [half](\ref half_float::half)s is just a no-op.
/// \tparam T destination type (half or built-in arithmetic type)
/// \tparam U source type (half or built-in arithmetic type)
/// \param arg value to cast
/// \return \a arg converted to destination type
template<typename T,typename U> T half_cast(const U &arg);
/// Cast to or from half-precision floating point number.
/// This casts between [half](\ref half_float::half) and any built-in arithmetic type. The values are converted directly
/// using the given rounding mode, without any roundtrip over `float` that a `static_cast` would otherwise do.
///
/// Using this cast with neither of the two types being a [half](\ref half_float::half) or with any of the two types
/// not being a built-in arithmetic type (apart from [half](\ref half_float::half), of course) results in a compiler
/// error and casting between [half](\ref half_float::half)s is just a no-op.
/// \tparam T destination type (half or built-in arithmetic type)
/// \tparam R rounding mode to use (see [std::float_round_style](http://en.cppreference.com/w/cpp/types/numeric_limits/float_round_style))
/// \tparam U source type (half or built-in arithmetic type)
/// \param arg value to cast
/// \return \a arg converted to destination type
template<typename T,std::float_round_style R,typename U> T half_cast(const U &arg);
/// \}
/// Library-defined half-precision literals.
/// Import this namespace to enable half-precision floating point literals (of course only if C++11 user-defined literals
/// are supported and enabled):
/// ~~~~{.cpp}
/// using namespace half_float::literal;
/// half_float::half = 4.2_h;
/// ~~~~
namespace literal
{
/// Half literal.
/// While this returns an actual half-precision value, half literals can unfortunately not be constant expressions due
/// to rather involved conversions.
/// \param value literal value
/// \return half with given value (if representable)
half operator""_h(long double value);
}
}
/// Extensions to the C++ standard library.
namespace std
{
/// Numeric limits for half-precision floats.
/// Because of the underlying single-precision implementation of many operations, it inherits some properties from
/// `std::numeric_limits<float>`.
///
/// **See also:** Documentation for [std::numeric_limits](http://en.cppreference.com/w/cpp/types/numeric_limits)
template<> struct numeric_limits<half_float::half> : public std::numeric_limits<float>
{
/// Supports signed values.
static constexpr bool is_signed = true;
/// Is not exact.
static constexpr bool is_exact = false;
/// Doesn't provide modulo arithmetic.
static constexpr bool is_modulo = false;
/// IEEE conformant.
static constexpr bool is_iec559 = true;
/// Supports infinity.
static constexpr bool has_infinity = true;
/// Supports quiet NaNs.
static constexpr bool has_quiet_NaN = true;
/// Supports subnormal values.
static constexpr std::float_denorm_style has_denorm = std::denorm_present;
/// Rounding mode.
/// Due to the mix of internal single-precision computations (using the rounding mode of the underlying
/// single-precision implementation) with the rounding mode of the single-to-half conversions, the actual rounding
/// mode might be `std::round_indeterminate` if the default half-precision rounding mode doesn't match the
/// single-precision rounding mode.
static constexpr std::float_round_style round_style = /* unspecified */;
/// Significant digits.
static constexpr int digits = 11;
/// Significant decimal digits.
static constexpr int digits10 = 3;
/// Required decimal digits to represent all possible values.
static constexpr int max_digits10 = 5;
/// Number base.
static constexpr int radix = 2;
/// One more than smallest exponent.
static constexpr int min_exponent = -13;
/// Smallest normalized representable power of 10.
static constexpr int min_exponent10 = -4;
/// One more than largest exponent
static constexpr int max_exponent = 16;
/// Largest finitely representable power of 10.
static constexpr int max_exponent10 = 4;
/// Smallest positive normal value.
static constexpr half_float::half min() noexcept;
/// Smallest finite value.
static constexpr half_float::half lowest() noexcept;
/// Largest finite value.
static constexpr half_float::half max() noexcept;
/// Difference between one and next representable value.
static constexpr half_float::half epsilon() noexcept;
/// Maximum rounding error.
static constexpr half_float::half round_error() noexcept;
/// Positive infinity.
static constexpr half_float::half infinity() noexcept;
/// Quiet NaN.
static constexpr half_float::half quiet_NaN() noexcept;
/// Signalling NaN.
static constexpr half_float::half signaling_NaN() noexcept;
/// Smallest positive subnormal value.
static constexpr half_float::half denorm_min() noexcept;
};
/// Hash function for half-precision floats.
/// This is only defined if C++11 `std::hash` is supported and enabled.
///
/// **See also:** Documentation for [std::hash](http://en.cppreference.com/w/cpp/utility/hash)
template<> struct hash<half_float::half>
{
/// Type of function argument.
typedef half_float::half argument_type;
/// Function return type.
typedef std::size_t result_type;
/// Compute hash function.
/// \param arg half to hash
/// \return hash value
std::size_t operator()(half_float::half arg) const;
};
}