MU Library
half_float::half Class Reference

#include <half.hpp>

Public Member Functions

Construction and assignment
HALF_CONSTEXPR half () HALF_NOEXCEPT
 
 half (float rhs)
 
 operator float () const
 
halfoperator= (float rhs)
 
Arithmetic updates
halfoperator+= (half rhs)
 
halfoperator-= (half rhs)
 
halfoperator*= (half rhs)
 
halfoperator/= (half rhs)
 
halfoperator+= (float rhs)
 
halfoperator-= (float rhs)
 
halfoperator*= (float rhs)
 
halfoperator/= (float rhs)
 
Increment and decrement
halfoperator++ ()
 
halfoperator-- ()
 
half operator++ (int)
 
half operator-- (int)
 

Friends

template<typename , typename , std::float_round_style >
struct detail::half_caster
 
class std::numeric_limits< half >
 
HALF_CONSTEXPR_NOERR bool operator== (half, half)
 
HALF_CONSTEXPR_NOERR bool operator!= (half, half)
 
HALF_CONSTEXPR_NOERR bool operator< (half, half)
 
HALF_CONSTEXPR_NOERR bool operator> (half, half)
 
HALF_CONSTEXPR_NOERR bool operator<= (half, half)
 
HALF_CONSTEXPR_NOERR bool operator>= (half, half)
 
HALF_CONSTEXPR half operator- (half)
 
half operator+ (half, half)
 
half operator- (half, half)
 
half operator* (half, half)
 
half operator/ (half, half)
 
HALF_CONSTEXPR half fabs (half)
 
half fmod (half, half)
 
half remainder (half, half)
 
half remquo (half, half, int *)
 
half fma (half, half, half)
 
HALF_CONSTEXPR_NOERR half fmax (half, half)
 
HALF_CONSTEXPR_NOERR half fmin (half, half)
 
half fdim (half, half)
 
half nanh (const char *)
 
half exp (half)
 
half exp2 (half)
 
half expm1 (half)
 
half log (half)
 
half log10 (half)
 
half log2 (half)
 
half log1p (half)
 
half sqrt (half)
 
half rsqrt (half)
 
half cbrt (half)
 
half hypot (half, half)
 
half hypot (half, half, half)
 
half pow (half, half)
 
void sincos (half, half *, half *)
 
half sin (half)
 
half cos (half)
 
half tan (half)
 
half asin (half)
 
half acos (half)
 
half atan (half)
 
half atan2 (half, half)
 
half sinh (half)
 
half cosh (half)
 
half tanh (half)
 
half asinh (half)
 
half acosh (half)
 
half atanh (half)
 
half erf (half)
 
half erfc (half)
 
half lgamma (half)
 
half tgamma (half)
 
half ceil (half)
 
half floor (half)
 
half trunc (half)
 
half round (half)
 
long lround (half)
 
half rint (half)
 
long lrint (half)
 
half nearbyint (half)
 
half frexp (half, int *)
 
half scalbln (half, long)
 
half modf (half, half *)
 
int ilogb (half)
 
half logb (half)
 
half nextafter (half, half)
 
half nexttoward (half, long double)
 
HALF_CONSTEXPR half copysign (half, half)
 
HALF_CONSTEXPR int fpclassify (half)
 
HALF_CONSTEXPR bool isfinite (half)
 
HALF_CONSTEXPR bool isinf (half)
 
HALF_CONSTEXPR bool isnan (half)
 
HALF_CONSTEXPR bool isnormal (half)
 
HALF_CONSTEXPR bool signbit (half)
 
HALF_CONSTEXPR bool isgreater (half, half)
 
HALF_CONSTEXPR bool isgreaterequal (half, half)
 
HALF_CONSTEXPR bool isless (half, half)
 
HALF_CONSTEXPR bool islessequal (half, half)
 
HALF_CONSTEXPR bool islessgreater (half, half)
 

Detailed Description

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.

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.

Definition at line 5090 of file half.hpp.

Constructor & Destructor Documentation

◆ half() [1/2]

HALF_CONSTEXPR half_float::half::half ( )
inline

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.

Definition at line 5099 of file half.hpp.

5099  : data_()
5100  {
5101  }

◆ half() [2/2]

half_float::half::half ( float  rhs)
inlineexplicit

Conversion constructor.

Parameters
rhsfloat to convert
Exceptions
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 5106 of file half.hpp.

5107  : data_(static_cast<detail::uint16>(detail::float2half<round_style>(rhs)))
5108  {
5109  }
unsigned short uint16
Unsigned integer of (at least) 16 bits width.
Definition: half.hpp:593

Member Function Documentation

◆ operator float()

half_float::half::operator float ( ) const
inline

Conversion to single-precision.

Returns
single precision value representing expression value

Definition at line 5113 of file half.hpp.

5114  {
5115  return detail::half2float<float>(data_);
5116  }

◆ operator*=() [1/2]

half& half_float::half::operator*= ( float  rhs)
inline

Arithmetic assignment.

Parameters
rhssingle-precision value to multiply with
Returns
reference to this half
Exceptions
FE_...according to operator=()

Definition at line 5194 of file half.hpp.

5195  {
5196  return *this = *this * rhs;
5197  }

◆ operator*=() [2/2]

half& half_float::half::operator*= ( half  rhs)
inline

Arithmetic assignment.

Template Parameters
Ttype of concrete half expression
Parameters
rhshalf expression to multiply with
Returns
reference to this half
Exceptions
FE_...according to operator*(half,half)

Definition at line 5157 of file half.hpp.

5158  {
5159  return *this = *this * rhs;
5160  }

◆ operator++() [1/2]

half& half_float::half::operator++ ( )
inline

Prefix increment.

Returns
incremented half value
Exceptions
FE_...according to operator+(half,half)

Definition at line 5215 of file half.hpp.

5216  {
5217  return *this = *this + half(detail::binary, 0x3C00);
5218  }
HALF_CONSTEXPR half() HALF_NOEXCEPT
Definition: half.hpp:5099
HALF_CONSTEXPR_CONST binary_t binary
Tag for binary construction.
Definition: half.hpp:635

◆ operator++() [2/2]

half half_float::half::operator++ ( int  )
inline

Postfix increment.

Returns
non-incremented half value
Exceptions
FE_...according to operator+(half,half)

Definition at line 5231 of file half.hpp.

5232  {
5233  half out(*this);
5234  ++*this;
5235  return out;
5236  }

◆ operator+=() [1/2]

half& half_float::half::operator+= ( float  rhs)
inline

Arithmetic assignment.

Parameters
rhssingle-precision value to add
Returns
reference to this half
Exceptions
FE_...according to operator=()

Definition at line 5176 of file half.hpp.

5177  {
5178  return *this = *this + rhs;
5179  }

◆ operator+=() [2/2]

half& half_float::half::operator+= ( half  rhs)
inline

Arithmetic assignment.

Template Parameters
Ttype of concrete half expression
Parameters
rhshalf expression to add
Returns
reference to this half
Exceptions
FE_...according to operator+(half,half)

Definition at line 5137 of file half.hpp.

5138  {
5139  return *this = *this + rhs;
5140  }

◆ operator--() [1/2]

half& half_float::half::operator-- ( )
inline

Prefix decrement.

Returns
decremented half value
Exceptions
FE_...according to operator-(half,half)

Definition at line 5223 of file half.hpp.

5224  {
5225  return *this = *this + half(detail::binary, 0xBC00);
5226  }

◆ operator--() [2/2]

half half_float::half::operator-- ( int  )
inline

Postfix decrement.

Returns
non-decremented half value
Exceptions
FE_...according to operator-(half,half)

Definition at line 5241 of file half.hpp.

5242  {
5243  half out(*this);
5244  --*this;
5245  return out;
5246  }

◆ operator-=() [1/2]

half& half_float::half::operator-= ( float  rhs)
inline

Arithmetic assignment.

Parameters
rhssingle-precision value to subtract
Returns
reference to this half
Exceptions
FE_...according to operator=()

Definition at line 5185 of file half.hpp.

5186  {
5187  return *this = *this - rhs;
5188  }

◆ operator-=() [2/2]

half& half_float::half::operator-= ( half  rhs)
inline

Arithmetic assignment.

Template Parameters
Ttype of concrete half expression
Parameters
rhshalf expression to subtract
Returns
reference to this half
Exceptions
FE_...according to operator-(half,half)

Definition at line 5147 of file half.hpp.

5148  {
5149  return *this = *this - rhs;
5150  }

◆ operator/=() [1/2]

half& half_float::half::operator/= ( float  rhs)
inline

Arithmetic assignment.

Parameters
rhssingle-precision value to divide by
Returns
reference to this half
Exceptions
FE_...according to operator=()

Definition at line 5203 of file half.hpp.

5204  {
5205  return *this = *this / rhs;
5206  }

◆ operator/=() [2/2]

half& half_float::half::operator/= ( half  rhs)
inline

Arithmetic assignment.

Template Parameters
Ttype of concrete half expression
Parameters
rhshalf expression to divide by
Returns
reference to this half
Exceptions
FE_...according to operator/(half,half)

Definition at line 5167 of file half.hpp.

5168  {
5169  return *this = *this / rhs;
5170  }

◆ operator=()

half& half_float::half::operator= ( float  rhs)
inline

Assignment operator.

Parameters
rhssingle-precision value to copy from
Returns
reference to this half
Exceptions
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 5122 of file half.hpp.

5123  {
5124  data_ = static_cast<detail::uint16>(detail::float2half<round_style>(rhs));
5125  return *this;
5126  }

Friends And Related Function Documentation

◆ acos

half acos ( half  arg)
friend

Arc cosine function. This function is exact to rounding for all rounding modes.

See also: Documentation for std::acos.

Parameters
argfunction argument
Returns
arc cosine value of arg
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN or if abs(arg) > 1
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 6895 of file half.hpp.

6896 {
6897 #ifdef HALF_ARITHMETIC_TYPE
6898  return half(detail::binary, detail::float2half<half::round_style>(std::acos(detail::half2float<detail::internal_t>(arg.data_))));
6899 #else
6900  unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ >> 15;
6901  if (!abs)
6902  return half(detail::binary, detail::rounded<half::round_style, true>(0x3E48, 0, 1));
6903  if (abs >= 0x3C00)
6904  return half(detail::binary, (abs > 0x7C00) ? detail::signal(arg.data_) : (abs > 0x3C00) ? detail::invalid()
6905  : sign ? detail::rounded<half::round_style, true>(0x4248, 0, 1)
6906  : 0);
6907  std::pair<detail::uint32, detail::uint32> cs = detail::atan2_args(abs);
6908  detail::uint32 m = detail::atan2(cs.second, cs.first, 28);
6909  return half(detail::binary, detail::fixed2half<half::round_style, 31, false, true, true>(sign ? (0xC90FDAA2 - m) : m, 15, 0, sign));
6910 #endif
6911 }
std::pair< uint32, uint32 > atan2_args(unsigned int abs)
Definition: half.hpp:4640
uint32 atan2(uint32 my, uint32 mx, unsigned int n=31)
Definition: half.hpp:4566
HALF_CONSTEXPR_NOERR unsigned int signal(unsigned int nan)
Definition: half.hpp:797
HALF_CONSTEXPR_NOERR unsigned int invalid()
Definition: half.hpp:850
unsigned long uint32
Fastest unsigned integer of (at least) 32 bits width.
Definition: half.hpp:596
HALF_CONSTEXPR half abs(half arg)
Definition: half.hpp:5905
half acos(half arg)
Definition: half.hpp:6895

◆ acosh

half acosh ( half  arg)
friend

Hyperbolic area cosine. This function is exact to rounding for all rounding modes.

See also: Documentation for std::acosh.

Parameters
argfunction argument
Returns
area cosine value of arg
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN or arguments <1
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 7126 of file half.hpp.

7127 {
7128 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
7129  return half(detail::binary, detail::float2half<half::round_style>(std::acosh(detail::half2float<detail::internal_t>(arg.data_))));
7130 #else
7131  int abs = arg.data_ & 0x7FFF;
7132  if ((arg.data_ & 0x8000) || abs < 0x3C00)
7133  return half(detail::binary, (abs <= 0x7C00) ? detail::invalid() : detail::signal(arg.data_));
7134  if (abs == 0x3C00)
7135  return half(detail::binary, 0);
7136  if (arg.data_ >= 0x7C00)
7137  return (abs > 0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
7138  return half(detail::binary, detail::area<half::round_style, false>(arg.data_));
7139 #endif
7140 }
half acosh(half arg)
Definition: half.hpp:7126

◆ asin

half asin ( half  arg)
friend

Arc sine. This function is exact to rounding for all rounding modes.

See also: Documentation for std::asin.

Parameters
argfunction argument
Returns
arc sine value of arg
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN or if abs(arg) > 1
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 6866 of file half.hpp.

6867 {
6868 #ifdef HALF_ARITHMETIC_TYPE
6869  return half(detail::binary, detail::float2half<half::round_style>(std::asin(detail::half2float<detail::internal_t>(arg.data_))));
6870 #else
6871  unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000;
6872  if (!abs)
6873  return arg;
6874  if (abs >= 0x3C00)
6875  return half(detail::binary, (abs > 0x7C00) ? detail::signal(arg.data_) : (abs > 0x3C00) ? detail::invalid()
6876  : detail::rounded<half::round_style, true>(sign | 0x3E48, 0, 1));
6877  if (abs < 0x2900)
6878  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_, 0, 1));
6879  if (half::round_style != std::round_to_nearest && (abs == 0x2B44 || abs == 0x2DC3))
6880  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_ + 1, 1, 1));
6881  std::pair<detail::uint32, detail::uint32> sc = detail::atan2_args(abs);
6882  detail::uint32 m = detail::atan2(sc.first, sc.second, (half::round_style == std::round_to_nearest) ? 27 : 26);
6883  return half(detail::binary, detail::fixed2half<half::round_style, 30, false, true, true>(m, 14, sign));
6884 #endif
6885 }
half asin(half arg)
Definition: half.hpp:6866

◆ asinh

half asinh ( half  arg)
friend

Hyperbolic area sine. This function is exact to rounding for all rounding modes.

See also: Documentation for std::asinh.

Parameters
argfunction argument
Returns
area sine value of arg
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 7096 of file half.hpp.

7097 {
7098 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
7099  return half(detail::binary, detail::float2half<half::round_style>(std::asinh(detail::half2float<detail::internal_t>(arg.data_))));
7100 #else
7101  int abs = arg.data_ & 0x7FFF;
7102  if (!abs || abs >= 0x7C00)
7103  return (abs > 0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
7104  if (abs <= 0x2900)
7105  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_ - 1, 1, 1));
7106  if (half::round_style != std::round_to_nearest)
7107  switch (abs)
7108  {
7109  case 0x32D4:
7110  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_ - 13, 1, 1));
7111  case 0x3B5B:
7112  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_ - 197, 1, 1));
7113  }
7114  return half(detail::binary, detail::area<half::round_style, true>(arg.data_));
7115 #endif
7116 }
half asinh(half arg)
Definition: half.hpp:7096

◆ atan

half atan ( half  arg)
friend

Arc tangent function. This function is exact to rounding for all rounding modes.

See also: Documentation for std::atan.

Parameters
argfunction argument
Returns
arc tangent value of arg
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 6921 of file half.hpp.

6922 {
6923 #ifdef HALF_ARITHMETIC_TYPE
6924  return half(detail::binary, detail::float2half<half::round_style>(std::atan(detail::half2float<detail::internal_t>(arg.data_))));
6925 #else
6926  unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000;
6927  if (!abs)
6928  return arg;
6929  if (abs >= 0x7C00)
6930  return half(detail::binary, (abs == 0x7C00) ? detail::rounded<half::round_style, true>(sign | 0x3E48, 0, 1) : detail::signal(arg.data_));
6931  if (abs <= 0x2700)
6932  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_ - 1, 1, 1));
6933  int exp = (abs >> 10) + (abs <= 0x3FF);
6934  detail::uint32 my = (abs & 0x3FF) | ((abs > 0x3FF) << 10);
6935  detail::uint32 m = (exp > 15) ? detail::atan2(my << 19, 0x20000000 >> (exp - 15), (half::round_style == std::round_to_nearest) ? 26 : 24) : detail::atan2(my << (exp + 4), 0x20000000, (half::round_style == std::round_to_nearest) ? 30 : 28);
6936  return half(detail::binary, detail::fixed2half<half::round_style, 30, false, true, true>(m, 14, sign));
6937 #endif
6938 }
friend half exp(half)
Definition: half.hpp:6111
half atan(half arg)
Definition: half.hpp:6921

◆ atan2

half atan2 ( half  y,
half  x 
)
friend

Arc tangent function. This function may be 1 ULP off the correctly rounded exact result in ~0.005% of inputs for std::round_to_nearest, in ~0.1% of inputs for std::round_toward_zero and in ~0.02% of inputs for any other rounding mode.

See also: Documentation for std::atan2.

Parameters
ynumerator
xdenominator
Returns
arc tangent value
Exceptions
MU_HALF_FE_INVALIDif x or y is signaling NaN
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 6950 of file half.hpp.

6951 {
6952 #ifdef HALF_ARITHMETIC_TYPE
6953  return half(detail::binary, detail::float2half<half::round_style>(std::atan2(detail::half2float<detail::internal_t>(y.data_), detail::half2float<detail::internal_t>(x.data_))));
6954 #else
6955  unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, signx = x.data_ >> 15, signy = y.data_ & 0x8000;
6956  if (absx >= 0x7C00 || absy >= 0x7C00)
6957  {
6958  if (absx > 0x7C00 || absy > 0x7C00)
6959  return half(detail::binary, detail::signal(x.data_, y.data_));
6960  if (absy == 0x7C00)
6961  return half(detail::binary, (absx < 0x7C00) ? detail::rounded<half::round_style, true>(signy | 0x3E48, 0, 1) : signx ? detail::rounded<half::round_style, true>(signy | 0x40B6, 0, 1)
6962  : detail::rounded<half::round_style, true>(signy | 0x3A48, 0, 1));
6963  return (x.data_ == 0x7C00) ? half(detail::binary, signy) : half(detail::binary, detail::rounded<half::round_style, true>(signy | 0x4248, 0, 1));
6964  }
6965  if (!absy)
6966  return signx ? half(detail::binary, detail::rounded<half::round_style, true>(signy | 0x4248, 0, 1)) : y;
6967  if (!absx)
6968  return half(detail::binary, detail::rounded<half::round_style, true>(signy | 0x3E48, 0, 1));
6969  int d = (absy >> 10) + (absy <= 0x3FF) - (absx >> 10) - (absx <= 0x3FF);
6970  if (d > (signx ? 18 : 12))
6971  return half(detail::binary, detail::rounded<half::round_style, true>(signy | 0x3E48, 0, 1));
6972  if (signx && d < -11)
6973  return half(detail::binary, detail::rounded<half::round_style, true>(signy | 0x4248, 0, 1));
6974  if (!signx && d < ((half::round_style == std::round_toward_zero) ? -15 : -9))
6975  {
6976  for (; absy < 0x400; absy <<= 1, --d)
6977  ;
6978  detail::uint32 mx = ((absx << 1) & 0x7FF) | 0x800, my = ((absy << 1) & 0x7FF) | 0x800;
6979  int i = my < mx;
6980  d -= i;
6981  if (d < -25)
6982  return half(detail::binary, detail::underflow<half::round_style>(signy));
6983  my <<= 11 + i;
6984  return half(detail::binary, detail::fixed2half<half::round_style, 11, false, false, true>(my / mx, d + 14, signy, my % mx != 0));
6985  }
6986  detail::uint32 m = detail::atan2(((absy & 0x3FF) | ((absy > 0x3FF) << 10)) << (19 + ((d < 0) ? d : (d > 0) ? 0
6987  : -1)),
6988  ((absx & 0x3FF) | ((absx > 0x3FF) << 10)) << (19 - ((d > 0) ? d : (d < 0) ? 0
6989  : 1)));
6990  return half(detail::binary, detail::fixed2half<half::round_style, 31, false, true, true>(signx ? (0xC90FDAA2 - m) : m, 15, signy, signx));
6991 #endif
6992 }
HALF_CONSTEXPR_NOERR unsigned int rounded(unsigned int value, int g, int s)
Definition: half.hpp:928
half atan2(half y, half x)
Definition: half.hpp:6950

◆ atanh

half atanh ( half  arg)
friend

Hyperbolic area tangent. This function is exact to rounding for all rounding modes.

See also: Documentation for std::atanh.

Parameters
argfunction argument
Returns
area tangent value of arg
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN or if abs(arg) > 1
MU_HALF_FE_DIVBYZEROfor +/-1
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 7151 of file half.hpp.

7152 {
7153 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
7154  return half(detail::binary, detail::float2half<half::round_style>(std::atanh(detail::half2float<detail::internal_t>(arg.data_))));
7155 #else
7156  int abs = arg.data_ & 0x7FFF, exp = 0;
7157  if (!abs)
7158  return arg;
7159  if (abs >= 0x3C00)
7160  return half(detail::binary, (abs == 0x3C00) ? detail::pole(arg.data_ & 0x8000) : (abs <= 0x7C00) ? detail::invalid()
7161  : detail::signal(arg.data_));
7162  if (abs < 0x2700)
7163  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_, 0, 1));
7164  detail::uint32 m = static_cast<detail::uint32>((abs & 0x3FF) | ((abs > 0x3FF) << 10)) << ((abs >> 10) + (abs <= 0x3FF) + 6), my = 0x80000000 + m, mx = 0x80000000 - m;
7165  for (; mx < 0x80000000; mx <<= 1, ++exp)
7166  ;
7167  int i = my >= mx, s;
7168  return half(detail::binary, detail::log2_post<half::round_style, 0xB8AA3B2A>(detail::log2((detail::divide64(my >> i, mx, s) + 1) >> 1, 27) + 0x10, exp + i - 1, 16, arg.data_ & 0x8000));
7169 #endif
7170 }
uint32 log2(uint32 m, unsigned int n=32)
Definition: half.hpp:4458
uint32 divide64(uint32 x, uint32 y, int &s)
Definition: half.hpp:4273
HALF_CONSTEXPR_NOERR unsigned int pole(unsigned int sign=0)
Definition: half.hpp:862
half atanh(half arg)
Definition: half.hpp:7151

◆ cbrt

half cbrt ( half  arg)
friend

Cubic root. This function is exact to rounding for all rounding modes.

See also: Documentation for std::cbrt.

Parameters
argfunction argument
Returns
cubic root of arg
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN
MU_HALF_FE_INEXACTaccording to rounding

Definition at line 6454 of file half.hpp.

6455 {
6456 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
6457  return half(detail::binary, detail::float2half<half::round_style>(std::cbrt(detail::half2float<detail::internal_t>(arg.data_))));
6458 #else
6459  int abs = arg.data_ & 0x7FFF, exp = -15;
6460  if (!abs || abs == 0x3C00 || abs >= 0x7C00)
6461  return (abs > 0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
6462  for (; abs < 0x400; abs <<= 1, --exp)
6463  ;
6464  detail::uint32 ilog = exp + (abs >> 10), sign = detail::sign_mask(ilog), f, m = (((ilog << 27) + (detail::log2(static_cast<detail::uint32>((abs & 0x3FF) | 0x400) << 20, 24) >> 4)) ^ sign) - sign;
6465  for (exp = 2; m < 0x80000000; m <<= 1, --exp)
6466  ;
6467  m = detail::multiply64(m, 0xAAAAAAAB);
6468  int i = m >> 31, s;
6469  exp += i;
6470  m <<= 1 - i;
6471  if (exp < 0)
6472  {
6473  f = m >> -exp;
6474  exp = 0;
6475  }
6476  else
6477  {
6478  f = (m << exp) & 0x7FFFFFFF;
6479  exp = m >> (31 - exp);
6480  }
6481  m = detail::exp2(f, (half::round_style == std::round_to_nearest) ? 29 : 26);
6482  if (sign)
6483  {
6484  if (m > 0x80000000)
6485  {
6486  m = detail::divide64(0x80000000, m, s);
6487  ++exp;
6488  }
6489  exp = -exp;
6490  }
6491  return half(detail::binary, (half::round_style == std::round_to_nearest) ? detail::fixed2half<half::round_style, 31, false, false, false>(m, exp + 14, arg.data_ & 0x8000) : detail::fixed2half<half::round_style, 23, false, false, false>((m + 0x80) >> 8, exp + 14, arg.data_ & 0x8000));
6492 #endif
6493 }
uint32 exp2(uint32 m, unsigned int n=32)
Definition: half.hpp:4403
uint32 multiply64(uint32 x, uint32 y)
Definition: half.hpp:4259
uint32 sign_mask(uint32 arg)
Definition: half.hpp:693
half cbrt(half arg)
Definition: half.hpp:6454

◆ ceil

half ceil ( half  arg)
friend

Nearest integer not less than half value. See also: Documentation for std::ceil.

Parameters
arghalf to round
Returns
nearest integer not less than arg
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN
MU_HALF_FE_INEXACTif value had to be rounded

Definition at line 7290 of file half.hpp.

7291 {
7292  return half(detail::binary, detail::integral<std::round_toward_infinity, true, true>(arg.data_));
7293 }

◆ copysign

HALF_CONSTEXPR half copysign ( half  x,
half  y 
)
friend

Take sign. See also: Documentation for std::copysign.

Parameters
xvalue to change sign for
yvalue to take sign from
Returns
value equal to x in magnitude and to y in sign

Definition at line 7603 of file half.hpp.

7604 {
7605  return half(detail::binary, x.data_ ^ ((x.data_ ^ y.data_) & 0x8000));
7606 }

◆ cos

half cos ( half  arg)
friend

Cosine function. This function is exact to rounding for all rounding modes.

See also: Documentation for std::cos.

Parameters
argfunction argument
Returns
cosine value of arg
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN or infinity
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 6797 of file half.hpp.

6798 {
6799 #ifdef HALF_ARITHMETIC_TYPE
6800  return half(detail::binary, detail::float2half<half::round_style>(std::cos(detail::half2float<detail::internal_t>(arg.data_))));
6801 #else
6802  int abs = arg.data_ & 0x7FFF, k;
6803  if (!abs)
6804  return half(detail::binary, 0x3C00);
6805  if (abs >= 0x7C00)
6806  return half(detail::binary, (abs == 0x7C00) ? detail::invalid() : detail::signal(arg.data_));
6807  if (abs < 0x2500)
6808  return half(detail::binary, detail::rounded<half::round_style, true>(0x3BFF, 1, 1));
6809  if (half::round_style != std::round_to_nearest && abs == 0x598C)
6810  return half(detail::binary, detail::rounded<half::round_style, true>(0x80FC, 1, 1));
6811  std::pair<detail::uint32, detail::uint32> sc = detail::sincos(detail::angle_arg(abs, k), 28);
6812  detail::uint32 sign = -static_cast<detail::uint32>(((k >> 1) ^ k) & 1);
6813  return half(detail::binary, detail::fixed2half<half::round_style, 30, true, true, true>((((k & 1) ? sc.first : sc.second) ^ sign) - sign));
6814 #endif
6815 }
std::pair< uint32, uint32 > sincos(uint32 mz, unsigned int n=31)
Definition: half.hpp:4513
uint32 angle_arg(unsigned int abs, int &k)
Definition: half.hpp:4617
half cos(half arg)
Definition: half.hpp:6797

◆ cosh

half cosh ( half  arg)
friend

Hyperbolic cosine. This function is exact to rounding for all rounding modes.

See also: Documentation for std::cosh.

Parameters
argfunction argument
Returns
hyperbolic cosine value of arg
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 7036 of file half.hpp.

7037 {
7038 #ifdef HALF_ARITHMETIC_TYPE
7039  return half(detail::binary, detail::float2half<half::round_style>(std::cosh(detail::half2float<detail::internal_t>(arg.data_))));
7040 #else
7041  int abs = arg.data_ & 0x7FFF, exp;
7042  if (!abs)
7043  return half(detail::binary, 0x3C00);
7044  if (abs >= 0x7C00)
7045  return half(detail::binary, (abs > 0x7C00) ? detail::signal(arg.data_) : 0x7C00);
7046  std::pair<detail::uint32, detail::uint32> mm = detail::hyperbolic_args(abs, exp, (half::round_style == std::round_to_nearest) ? 23 : 26);
7047  detail::uint32 m = mm.first + mm.second, i = (~m & 0xFFFFFFFF) >> 31;
7048  m = (m >> i) | (m & i) | 0x80000000;
7049  if ((exp += 13 + i) > 29)
7050  return half(detail::binary, detail::overflow<half::round_style>());
7051  return half(detail::binary, detail::fixed2half<half::round_style, 31, false, false, true>(m, exp));
7052 #endif
7053 }
std::pair< uint32, uint32 > hyperbolic_args(unsigned int abs, int &exp, unsigned int n=32)
Definition: half.hpp:4665
half cosh(half arg)
Definition: half.hpp:7036

◆ detail::half_caster

template<typename , typename , std::float_round_style >
friend struct detail::half_caster
friend

Definition at line 5350 of file half.hpp.

◆ erf

half erf ( half  arg)
friend

Error function. This function may be 1 ULP off the correctly rounded exact result for any rounding mode in <0.5% of inputs.

See also: Documentation for std::erf.

Parameters
argfunction argument
Returns
error function value of arg
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 7185 of file half.hpp.

7186 {
7187 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
7188  return half(detail::binary, detail::float2half<half::round_style>(std::erf(detail::half2float<detail::internal_t>(arg.data_))));
7189 #else
7190  unsigned int abs = arg.data_ & 0x7FFF;
7191  if (!abs || abs >= 0x7C00)
7192  return (abs >= 0x7C00) ? half(detail::binary, (abs == 0x7C00) ? (arg.data_ - 0x4000) : detail::signal(arg.data_)) : arg;
7193  if (abs >= 0x4200)
7194  return half(detail::binary, detail::rounded<half::round_style, true>((arg.data_ & 0x8000) | 0x3BFF, 1, 1));
7195  return half(detail::binary, detail::erf<half::round_style, false>(arg.data_));
7196 #endif
7197 }
half erf(half arg)
Definition: half.hpp:7185

◆ erfc

half erfc ( half  arg)
friend

Complementary error function. This function may be 1 ULP off the correctly rounded exact result for any rounding mode in <0.5% of inputs.

See also: Documentation for std::erfc.

Parameters
argfunction argument
Returns
1 minus error function value of arg
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 7207 of file half.hpp.

7208 {
7209 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
7210  return half(detail::binary, detail::float2half<half::round_style>(std::erfc(detail::half2float<detail::internal_t>(arg.data_))));
7211 #else
7212  unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000;
7213  if (abs >= 0x7C00)
7214  return (abs >= 0x7C00) ? half(detail::binary, (abs == 0x7C00) ? (sign >> 1) : detail::signal(arg.data_)) : arg;
7215  if (!abs)
7216  return half(detail::binary, 0x3C00);
7217  if (abs >= 0x4400)
7218  return half(detail::binary, detail::rounded<half::round_style, true>((sign >> 1) - (sign >> 15), sign >> 15, 1));
7219  return half(detail::binary, detail::erf<half::round_style, true>(arg.data_));
7220 #endif
7221 }
half erfc(half arg)
Definition: half.hpp:7207

◆ exp

half exp ( half  arg)
friend

Exponential function. This function is exact to rounding for all rounding modes.

See also: Documentation for std::exp.

Parameters
argfunction argument
Returns
e raised to arg
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 6111 of file half.hpp.

6112 {
6113 #ifdef HALF_ARITHMETIC_TYPE
6114  return half(detail::binary, detail::float2half<half::round_style>(std::exp(detail::half2float<detail::internal_t>(arg.data_))));
6115 #else
6116  int abs = arg.data_ & 0x7FFF, e = (abs >> 10) + (abs <= 0x3FF), exp;
6117  if (!abs)
6118  return half(detail::binary, 0x3C00);
6119  if (abs >= 0x7C00)
6120  return half(detail::binary, (abs == 0x7C00) ? (0x7C00 & ((arg.data_ >> 15) - 1U)) : detail::signal(arg.data_));
6121  if (abs >= 0x4C80)
6122  return half(detail::binary, (arg.data_ & 0x8000) ? detail::underflow<half::round_style>() : detail::overflow<half::round_style>());
6123  detail::uint32 m = detail::multiply64(static_cast<detail::uint32>((abs & 0x3FF) + ((abs > 0x3FF) << 10)) << 21, 0xB8AA3B29);
6124  if (e < 14)
6125  {
6126  exp = 0;
6127  m >>= 14 - e;
6128  }
6129  else
6130  {
6131  exp = m >> (45 - e);
6132  m = (m << (e - 14)) & 0x7FFFFFFF;
6133  }
6134  return half(detail::binary, detail::exp2_post<half::round_style>(m, exp, (arg.data_ & 0x8000) != 0, 0, 26));
6135 #endif
6136 }
half exp(half arg)
Definition: half.hpp:6111

◆ exp2

half exp2 ( half  arg)
friend

Binary exponential. This function is exact to rounding for all rounding modes.

See also: Documentation for std::exp2.

Parameters
argfunction argument
Returns
2 raised to arg
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 6146 of file half.hpp.

6147 {
6148 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
6149  return half(detail::binary, detail::float2half<half::round_style>(std::exp2(detail::half2float<detail::internal_t>(arg.data_))));
6150 #else
6151  int abs = arg.data_ & 0x7FFF, e = (abs >> 10) + (abs <= 0x3FF), exp = (abs & 0x3FF) + ((abs > 0x3FF) << 10);
6152  if (!abs)
6153  return half(detail::binary, 0x3C00);
6154  if (abs >= 0x7C00)
6155  return half(detail::binary, (abs == 0x7C00) ? (0x7C00 & ((arg.data_ >> 15) - 1U)) : detail::signal(arg.data_));
6156  if (abs >= 0x4E40)
6157  return half(detail::binary, (arg.data_ & 0x8000) ? detail::underflow<half::round_style>() : detail::overflow<half::round_style>());
6158  return half(detail::binary, detail::exp2_post<half::round_style>((static_cast<detail::uint32>(exp) << (6 + e)) & 0x7FFFFFFF, exp >> (25 - e), (arg.data_ & 0x8000) != 0, 0, 28));
6159 #endif
6160 }
half exp2(half arg)
Definition: half.hpp:6146

◆ expm1

half expm1 ( half  arg)
friend

Exponential minus one. This function may be 1 ULP off the correctly rounded exact result in <0.05% of inputs for std::round_to_nearest and in <1% of inputs for any other rounding mode.

See also: Documentation for std::expm1.

Parameters
argfunction argument
Returns
e raised to arg and subtracted by 1
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 6171 of file half.hpp.

6172 {
6173 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
6174  return half(detail::binary, detail::float2half<half::round_style>(std::expm1(detail::half2float<detail::internal_t>(arg.data_))));
6175 #else
6176  unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000, e = (abs >> 10) + (abs <= 0x3FF), exp;
6177  if (!abs)
6178  return arg;
6179  if (abs >= 0x7C00)
6180  return half(detail::binary, (abs == 0x7C00) ? (0x7C00 + (sign >> 1)) : detail::signal(arg.data_));
6181  if (abs >= 0x4A00)
6182  return half(detail::binary, (arg.data_ & 0x8000) ? detail::rounded<half::round_style, true>(0xBBFF, 1, 1) : detail::overflow<half::round_style>());
6183  detail::uint32 m = detail::multiply64(static_cast<detail::uint32>((abs & 0x3FF) + ((abs > 0x3FF) << 10)) << 21, 0xB8AA3B29);
6184  if (e < 14)
6185  {
6186  exp = 0;
6187  m >>= 14 - e;
6188  }
6189  else
6190  {
6191  exp = m >> (45 - e);
6192  m = (m << (e - 14)) & 0x7FFFFFFF;
6193  }
6194  m = detail::exp2(m);
6195  if (sign)
6196  {
6197  int s = 0;
6198  if (m > 0x80000000)
6199  {
6200  ++exp;
6201  m = detail::divide64(0x80000000, m, s);
6202  }
6203  m = 0x80000000 - ((m >> exp) | ((m & ((static_cast<detail::uint32>(1) << exp) - 1)) != 0) | s);
6204  exp = 0;
6205  }
6206  else
6207  m -= (exp < 31) ? (0x80000000 >> exp) : 1;
6208  for (exp += 14; m < 0x80000000 && exp; m <<= 1, --exp)
6209  ;
6210  if (exp > 29)
6211  return half(detail::binary, detail::overflow<half::round_style>());
6212  return half(detail::binary, detail::rounded<half::round_style, true>(sign + (exp << 10) + (m >> 21), (m >> 20) & 1, (m & 0xFFFFF) != 0));
6213 #endif
6214 }
half expm1(half arg)
Definition: half.hpp:6171

◆ fabs

HALF_CONSTEXPR half fabs ( half  arg)
friend

Absolute value. See also: Documentation for std::fabs.

Parameters
argoperand
Returns
absolute value of arg

Definition at line 5896 of file half.hpp.

5897 {
5898  return half(detail::binary, arg.data_ & 0x7FFF);
5899 }

◆ fdim

half fdim ( half  x,
half  y 
)
friend

Positive difference. This function is exact to rounding for all rounding modes.

See also: Documentation for std::fdim.

Parameters
xfirst operand
ysecond operand
Returns
x - y or 0 if difference negative
Exceptions
FE_...according to operator-(half,half)

Definition at line 6079 of file half.hpp.

6080 {
6081  if (isnan(x) || isnan(y))
6082  return half(detail::binary, detail::signal(x.data_, y.data_));
6083  return (x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) <= (y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) ? half(detail::binary, 0) : (x - y);
6084 }
friend HALF_CONSTEXPR bool isnan(half)
Definition: half.hpp:7654

◆ floor

half floor ( half  arg)
friend

Nearest integer not greater than half value. See also: Documentation for std::floor.

Parameters
arghalf to round
Returns
nearest integer not greater than arg
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN
MU_HALF_FE_INEXACTif value had to be rounded

Definition at line 7301 of file half.hpp.

7302 {
7303  return half(detail::binary, detail::integral<std::round_toward_neg_infinity, true, true>(arg.data_));
7304 }

◆ fma

half fma ( half  x,
half  y,
half  z 
)
friend

Fused multiply add. This function is exact to rounding for all rounding modes.

See also: Documentation for std::fma.

Parameters
xfirst operand
ysecond operand
zthird operand
Returns
( x * y ) + z rounded as one operation.
Exceptions
MU_HALF_FE_INVALIDaccording to operator*() and operator+() unless any argument is a quiet NaN and no argument is a signaling NaN
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding the final addition

Definition at line 5982 of file half.hpp.

5983 {
5984 #ifdef HALF_ARITHMETIC_TYPE
5985  detail::internal_t fx = detail::half2float<detail::internal_t>(x.data_), fy = detail::half2float<detail::internal_t>(y.data_), fz = detail::half2float<detail::internal_t>(z.data_);
5986 #if HALF_ENABLE_CPP11_CMATH && FP_FAST_FMA
5987  return half(detail::binary, detail::float2half<half::round_style>(std::fma(fx, fy, fz)));
5988 #else
5989  return half(detail::binary, detail::float2half<half::round_style>(fx * fy + fz));
5990 #endif
5991 #else
5992  int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, absz = z.data_ & 0x7FFF, exp = -15;
5993  unsigned int sign = (x.data_ ^ y.data_) & 0x8000;
5994  bool sub = ((sign ^ z.data_) & 0x8000) != 0;
5995  if (absx >= 0x7C00 || absy >= 0x7C00 || absz >= 0x7C00)
5996  return (absx > 0x7C00 || absy > 0x7C00 || absz > 0x7C00) ? half(detail::binary, detail::signal(x.data_, y.data_, z.data_)) : (absx == 0x7C00) ? half(detail::binary, (!absy || (sub && absz == 0x7C00)) ? detail::invalid() : (sign | 0x7C00))
5997  : (absy == 0x7C00) ? half(detail::binary, (!absx || (sub && absz == 0x7C00)) ? detail::invalid() : (sign | 0x7C00))
5998  : z;
5999  if (!absx || !absy)
6000  return absz ? z : half(detail::binary, (half::round_style == std::round_toward_neg_infinity) ? (z.data_ | sign) : (z.data_ & sign));
6001  for (; absx < 0x400; absx <<= 1, --exp)
6002  ;
6003  for (; absy < 0x400; absy <<= 1, --exp)
6004  ;
6005  detail::uint32 m = static_cast<detail::uint32>((absx & 0x3FF) | 0x400) * static_cast<detail::uint32>((absy & 0x3FF) | 0x400);
6006  int i = m >> 21;
6007  exp += (absx >> 10) + (absy >> 10) + i;
6008  m <<= 3 - i;
6009  if (absz)
6010  {
6011  int expz = 0;
6012  for (; absz < 0x400; absz <<= 1, --expz)
6013  ;
6014  expz += absz >> 10;
6015  detail::uint32 mz = static_cast<detail::uint32>((absz & 0x3FF) | 0x400) << 13;
6016  if (expz > exp || (expz == exp && mz > m))
6017  {
6018  std::swap(m, mz);
6019  std::swap(exp, expz);
6020  if (sub)
6021  sign = z.data_ & 0x8000;
6022  }
6023  int d = exp - expz;
6024  mz = (d < 23) ? ((mz >> d) | ((mz & ((static_cast<detail::uint32>(1) << d) - 1)) != 0)) : 1;
6025  if (sub)
6026  {
6027  m = m - mz;
6028  if (!m)
6029  return half(detail::binary, static_cast<unsigned>(half::round_style == std::round_toward_neg_infinity) << 15);
6030  for (; m < 0x800000; m <<= 1, --exp)
6031  ;
6032  }
6033  else
6034  {
6035  m += mz;
6036  i = m >> 24;
6037  m = (m >> i) | (m & i);
6038  exp += i;
6039  }
6040  }
6041  if (exp > 30)
6042  return half(detail::binary, detail::overflow<half::round_style>(sign));
6043  else if (exp < -10)
6044  return half(detail::binary, detail::underflow<half::round_style>(sign));
6045  return half(detail::binary, detail::fixed2half<half::round_style, 23, false, false, false>(m, exp - 1, sign));
6046 #endif
6047 }
half fma(half x, half y, half z)
Definition: half.hpp:5982

◆ fmax

HALF_CONSTEXPR_NOERR half fmax ( half  x,
half  y 
)
friend

Maximum of half expressions. See also: Documentation for std::fmax.

Parameters
xfirst operand
ysecond operand
Returns
maximum of operands, ignoring quiet NaNs
Exceptions
MU_HALF_FE_INVALIDif x or y is signaling NaN

Definition at line 6055 of file half.hpp.

6056 {
6057  return half(detail::binary, (!isnan(y) && (isnan(x) || (x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) < (y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))))) ? detail::select(y.data_, x.data_) : detail::select(x.data_, y.data_));
6058 }
HALF_CONSTEXPR_NOERR unsigned int select(unsigned int x, unsigned int HALF_UNUSED_NOERR(y))
Definition: half.hpp:838

◆ fmin

HALF_CONSTEXPR_NOERR half fmin ( half  x,
half  y 
)
friend

Minimum of half expressions. See also: Documentation for std::fmin.

Parameters
xfirst operand
ysecond operand
Returns
minimum of operands, ignoring quiet NaNs
Exceptions
MU_HALF_FE_INVALIDif x or y is signaling NaN

Definition at line 6066 of file half.hpp.

6067 {
6068  return half(detail::binary, (!isnan(y) && (isnan(x) || (x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) > (y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))))) ? detail::select(y.data_, x.data_) : detail::select(x.data_, y.data_));
6069 }

◆ fmod

half fmod ( half  x,
half  y 
)
friend

Remainder of division. See also: Documentation for std::fmod.

Parameters
xfirst operand
ysecond operand
Returns
remainder of floating-point division.
Exceptions
MU_HALF_FE_INVALIDif x is infinite or y is 0 or if x or y is signaling NaN

Definition at line 5916 of file half.hpp.

5917 {
5918  unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, sign = x.data_ & 0x8000;
5919  if (absx >= 0x7C00 || absy >= 0x7C00)
5920  return half(detail::binary, (absx > 0x7C00 || absy > 0x7C00) ? detail::signal(x.data_, y.data_) : (absx == 0x7C00) ? detail::invalid()
5921  : x.data_);
5922  if (!absy)
5923  return half(detail::binary, detail::invalid());
5924  if (!absx)
5925  return x;
5926  if (absx == absy)
5927  return half(detail::binary, sign);
5928  return half(detail::binary, sign | detail::mod<false, false>(absx, absy));
5929 }

◆ fpclassify

HALF_CONSTEXPR int fpclassify ( half  arg)
friend

Classify floating-point value. See also: Documentation for std::fpclassify.

Parameters
argnumber to classify
Return values
FP_ZEROfor positive and negative zero
FP_SUBNORMALfor subnormal numbers
FP_INFINITYfor positive and negative infinity
FP_NANfor NaNs
FP_NORMALfor all other (normal) values

Definition at line 7621 of file half.hpp.

7622 {
7623  return !(arg.data_ & 0x7FFF) ? FP_ZERO : ((arg.data_ & 0x7FFF) < 0x400) ? FP_SUBNORMAL
7624  : ((arg.data_ & 0x7FFF) < 0x7C00) ? FP_NORMAL
7625  : ((arg.data_ & 0x7FFF) == 0x7C00) ? FP_INFINITE
7626  : FP_NAN;
7627 }
#define FP_NAN
Definition: half.hpp:436
#define FP_ZERO
Definition: half.hpp:433
#define FP_INFINITE
Definition: half.hpp:439
#define FP_NORMAL
Definition: half.hpp:442
#define FP_SUBNORMAL
Definition: half.hpp:430

◆ frexp

half frexp ( half  arg,
int *  exp 
)
friend

Decompress floating-point number. See also: Documentation for std::frexp.

Parameters
argnumber to decompress
expaddress to store exponent at
Returns
significant in range [0.5, 1)
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN

Definition at line 7403 of file half.hpp.

7404 {
7405  *exp = 0;
7406  unsigned int abs = arg.data_ & 0x7FFF;
7407  if (abs >= 0x7C00 || !abs)
7408  return (abs > 0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
7409  for (; abs < 0x400; abs <<= 1, --*exp)
7410  ;
7411  *exp += (abs >> 10) - 14;
7412  return half(detail::binary, (arg.data_ & 0x8000) | 0x3800 | (abs & 0x3FF));
7413 }

◆ hypot [1/2]

half hypot ( half  x,
half  y 
)
friend

Hypotenuse function. This function is exact to rounding for all rounding modes.

See also: Documentation for std::hypot.

Parameters
xfirst argument
ysecond argument
Returns
square root of sum of squares without internal over- or underflows
Exceptions
MU_HALF_FE_INVALIDif x or y is signaling NaN
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding of the final square root

Definition at line 6504 of file half.hpp.

6505 {
6506 #ifdef HALF_ARITHMETIC_TYPE
6507  detail::internal_t fx = detail::half2float<detail::internal_t>(x.data_), fy = detail::half2float<detail::internal_t>(y.data_);
6508 #if HALF_ENABLE_CPP11_CMATH
6509  return half(detail::binary, detail::float2half<half::round_style>(std::hypot(fx, fy)));
6510 #else
6511  return half(detail::binary, detail::float2half<half::round_style>(std::sqrt(fx * fx + fy * fy)));
6512 #endif
6513 #else
6514  int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, expx = 0, expy = 0;
6515  if (absx >= 0x7C00 || absy >= 0x7C00)
6516  return half(detail::binary, (absx == 0x7C00) ? detail::select(0x7C00, y.data_) : (absy == 0x7C00) ? detail::select(0x7C00, x.data_)
6517  : detail::signal(x.data_, y.data_));
6518  if (!absx)
6519  return half(detail::binary, absy ? detail::check_underflow(absy) : 0);
6520  if (!absy)
6522  if (absy > absx)
6523  std::swap(absx, absy);
6524  for (; absx < 0x400; absx <<= 1, --expx)
6525  ;
6526  for (; absy < 0x400; absy <<= 1, --expy)
6527  ;
6528  detail::uint32 mx = (absx & 0x3FF) | 0x400, my = (absy & 0x3FF) | 0x400;
6529  mx *= mx;
6530  my *= my;
6531  int ix = mx >> 21, iy = my >> 21;
6532  expx = 2 * (expx + (absx >> 10)) - 15 + ix;
6533  expy = 2 * (expy + (absy >> 10)) - 15 + iy;
6534  mx <<= 10 - ix;
6535  my <<= 10 - iy;
6536  int d = expx - expy;
6537  my = (d < 30) ? ((my >> d) | ((my & ((static_cast<detail::uint32>(1) << d) - 1)) != 0)) : 1;
6538  return half(detail::binary, detail::hypot_post<half::round_style>(mx + my, expx));
6539 #endif
6540 }
HALF_CONSTEXPR_NOERR unsigned int check_underflow(unsigned int arg)
Definition: half.hpp:874
half sqrt(half arg)
Definition: half.hpp:6390
half hypot(half x, half y, half z)
Definition: half.hpp:6552

◆ hypot [2/2]

half hypot ( half  x,
half  y,
half  z 
)
friend

Hypotenuse function. This function is exact to rounding for all rounding modes.

See also: Documentation for std::hypot.

Parameters
xfirst argument
ysecond argument
zthird argument
Returns
square root of sum of squares without internal over- or underflows
Exceptions
MU_HALF_FE_INVALIDif x, y or z is signaling NaN
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding of the final square root

Definition at line 6552 of file half.hpp.

6553 {
6554 #ifdef HALF_ARITHMETIC_TYPE
6555  detail::internal_t fx = detail::half2float<detail::internal_t>(x.data_), fy = detail::half2float<detail::internal_t>(y.data_), fz = detail::half2float<detail::internal_t>(z.data_);
6556  return half(detail::binary, detail::float2half<half::round_style>(std::sqrt(fx * fx + fy * fy + fz * fz)));
6557 #else
6558  int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, absz = z.data_ & 0x7FFF, expx = 0, expy = 0, expz = 0;
6559  if (!absx)
6560  return hypot(y, z);
6561  if (!absy)
6562  return hypot(x, z);
6563  if (!absz)
6564  return hypot(x, y);
6565  if (absx >= 0x7C00 || absy >= 0x7C00 || absz >= 0x7C00)
6566  return half(detail::binary, (absx == 0x7C00) ? detail::select(0x7C00, detail::select(y.data_, z.data_)) : (absy == 0x7C00) ? detail::select(0x7C00, detail::select(x.data_, z.data_))
6567  : (absz == 0x7C00) ? detail::select(0x7C00, detail::select(x.data_, y.data_))
6568  : detail::signal(x.data_, y.data_, z.data_));
6569  if (absz > absy)
6570  std::swap(absy, absz);
6571  if (absy > absx)
6572  std::swap(absx, absy);
6573  if (absz > absy)
6574  std::swap(absy, absz);
6575  for (; absx < 0x400; absx <<= 1, --expx)
6576  ;
6577  for (; absy < 0x400; absy <<= 1, --expy)
6578  ;
6579  for (; absz < 0x400; absz <<= 1, --expz)
6580  ;
6581  detail::uint32 mx = (absx & 0x3FF) | 0x400, my = (absy & 0x3FF) | 0x400, mz = (absz & 0x3FF) | 0x400;
6582  mx *= mx;
6583  my *= my;
6584  mz *= mz;
6585  int ix = mx >> 21, iy = my >> 21, iz = mz >> 21;
6586  expx = 2 * (expx + (absx >> 10)) - 15 + ix;
6587  expy = 2 * (expy + (absy >> 10)) - 15 + iy;
6588  expz = 2 * (expz + (absz >> 10)) - 15 + iz;
6589  mx <<= 10 - ix;
6590  my <<= 10 - iy;
6591  mz <<= 10 - iz;
6592  int d = expy - expz;
6593  mz = (d < 30) ? ((mz >> d) | ((mz & ((static_cast<detail::uint32>(1) << d) - 1)) != 0)) : 1;
6594  my += mz;
6595  if (my & 0x80000000)
6596  {
6597  my = (my >> 1) | (my & 1);
6598  if (++expy > expx)
6599  {
6600  std::swap(mx, my);
6601  std::swap(expx, expy);
6602  }
6603  }
6604  d = expx - expy;
6605  my = (d < 30) ? ((my >> d) | ((my & ((static_cast<detail::uint32>(1) << d) - 1)) != 0)) : 1;
6606  return half(detail::binary, detail::hypot_post<half::round_style>(mx + my, expx));
6607 #endif
6608 }
friend half hypot(half, half)
Definition: half.hpp:6504

◆ ilogb

int ilogb ( half  arg)
friend

Extract exponent. See also: Documentation for std::ilogb.

Parameters
argnumber to query
Returns
floating-point exponent
Return values
FP_ILOGB0for zero
FP_ILOGBNANfor NaN
INT_MAXfor infinity
Exceptions
MU_HALF_FE_INVALIDfor 0 or infinite values

Definition at line 7505 of file half.hpp.

7506 {
7507  int abs = arg.data_ & 0x7FFF, exp;
7508  if (!abs || abs >= 0x7C00)
7509  {
7511  return !abs ? FP_ILOGB0 : (abs == 0x7C00) ? INT_MAX
7512  : FP_ILOGBNAN;
7513  }
7514  for (exp = (abs >> 10) - 15; abs < 0x200; abs <<= 1, --exp)
7515  ;
7516  return exp;
7517 }
#define FP_ILOGBNAN
Definition: half.hpp:427
#define FP_ILOGB0
Definition: half.hpp:424
#define MU_HALF_FE_INVALID
Definition: half.hpp:41
void raise(int HALF_UNUSED_NOERR(flags), bool HALF_UNUSED_NOERR(cond)=true)
Definition: half.hpp:731

◆ isfinite

HALF_CONSTEXPR bool isfinite ( half  arg)
friend

Check if finite number. See also: Documentation for std::isfinite.

Parameters
argnumber to check
Return values
trueif neither infinity nor NaN
falseelse

Definition at line 7634 of file half.hpp.

7635 {
7636  return (arg.data_ & 0x7C00) != 0x7C00;
7637 }

◆ isgreater

HALF_CONSTEXPR bool isgreater ( half  x,
half  y 
)
friend

Quiet comparison for greater than. See also: Documentation for std::isgreater.

Parameters
xfirst operand
ysecond operand
Return values
trueif x greater than y
falseelse

Definition at line 7690 of file half.hpp.

7691 {
7692  return ((x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) + (x.data_ >> 15)) > ((y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) + (y.data_ >> 15)) && !isnan(x) && !isnan(y);
7693 }

◆ isgreaterequal

HALF_CONSTEXPR bool isgreaterequal ( half  x,
half  y 
)
friend

Quiet comparison for greater equal. See also: Documentation for std::isgreaterequal.

Parameters
xfirst operand
ysecond operand
Return values
trueif x greater equal y
falseelse

Definition at line 7701 of file half.hpp.

7702 {
7703  return ((x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) + (x.data_ >> 15)) >= ((y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) + (y.data_ >> 15)) && !isnan(x) && !isnan(y);
7704 }

◆ isinf

HALF_CONSTEXPR bool isinf ( half  arg)
friend

Check for infinity. See also: Documentation for std::isinf.

Parameters
argnumber to check
Return values
truefor positive or negative infinity
falseelse

Definition at line 7644 of file half.hpp.

7645 {
7646  return (arg.data_ & 0x7FFF) == 0x7C00;
7647 }

◆ isless

HALF_CONSTEXPR bool isless ( half  x,
half  y 
)
friend

Quiet comparison for less than. See also: Documentation for std::isless.

Parameters
xfirst operand
ysecond operand
Return values
trueif x less than y
falseelse

Definition at line 7712 of file half.hpp.

7713 {
7714  return ((x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) + (x.data_ >> 15)) < ((y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) + (y.data_ >> 15)) && !isnan(x) && !isnan(y);
7715 }

◆ islessequal

HALF_CONSTEXPR bool islessequal ( half  x,
half  y 
)
friend

Quiet comparison for less equal. See also: Documentation for std::islessequal.

Parameters
xfirst operand
ysecond operand
Return values
trueif x less equal y
falseelse

Definition at line 7723 of file half.hpp.

7724 {
7725  return ((x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) + (x.data_ >> 15)) <= ((y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) + (y.data_ >> 15)) && !isnan(x) && !isnan(y);
7726 }

◆ islessgreater

HALF_CONSTEXPR bool islessgreater ( half  x,
half  y 
)
friend

Quiet comarison for less or greater. See also: Documentation for std::islessgreater.

Parameters
xfirst operand
ysecond operand
Return values
trueif either less or greater
falseelse

Definition at line 7734 of file half.hpp.

7735 {
7736  return x.data_ != y.data_ && ((x.data_ | y.data_) & 0x7FFF) && !isnan(x) && !isnan(y);
7737 }

◆ isnan

HALF_CONSTEXPR bool isnan ( half  arg)
friend

Check for NaN. See also: Documentation for std::isnan.

Parameters
argnumber to check
Return values
truefor NaNs
falseelse

Definition at line 7654 of file half.hpp.

7655 {
7656  return (arg.data_ & 0x7FFF) > 0x7C00;
7657 }

◆ isnormal

HALF_CONSTEXPR bool isnormal ( half  arg)
friend

Check if normal number. See also: Documentation for std::isnormal.

Parameters
argnumber to check
Return values
trueif normal number
falseif either subnormal, zero, infinity or NaN

Definition at line 7664 of file half.hpp.

7665 {
7666  return ((arg.data_ & 0x7C00) != 0) && ((arg.data_ & 0x7C00) != 0x7C00);
7667 }

◆ lgamma

half lgamma ( half  arg)
friend

Natural logarithm of gamma function. This function may be 1 ULP off the correctly rounded exact result for any rounding mode in ~0.025% of inputs.

See also: Documentation for std::lgamma.

Parameters
argfunction argument
Returns
natural logarith of gamma function for arg
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN
MU_HALF_FE_DIVBYZEROfor 0 or negative integer arguments
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 7232 of file half.hpp.

7233 {
7234 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
7235  return half(detail::binary, detail::float2half<half::round_style>(std::lgamma(detail::half2float<detail::internal_t>(arg.data_))));
7236 #else
7237  int abs = arg.data_ & 0x7FFF;
7238  if (abs >= 0x7C00)
7239  return half(detail::binary, (abs == 0x7C00) ? 0x7C00 : detail::signal(arg.data_));
7240  if (!abs || arg.data_ >= 0xE400 || (arg.data_ >= 0xBC00 && !(abs & ((1 << (25 - (abs >> 10))) - 1))))
7241  return half(detail::binary, detail::pole());
7242  if (arg.data_ == 0x3C00 || arg.data_ == 0x4000)
7243  return half(detail::binary, 0);
7244  return half(detail::binary, detail::gamma<half::round_style, true>(arg.data_));
7245 #endif
7246 }
half lgamma(half arg)
Definition: half.hpp:7232

◆ log

half log ( half  arg)
friend

Natural logarithm. This function is exact to rounding for all rounding modes.

See also: Documentation for std::log.

Parameters
argfunction argument
Returns
logarithm of arg to base e
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN or negative argument
MU_HALF_FE_DIVBYZEROfor 0
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 6225 of file half.hpp.

6226 {
6227 #ifdef HALF_ARITHMETIC_TYPE
6228  return half(detail::binary, detail::float2half<half::round_style>(std::log(detail::half2float<detail::internal_t>(arg.data_))));
6229 #else
6230  int abs = arg.data_ & 0x7FFF, exp = -15;
6231  if (!abs)
6232  return half(detail::binary, detail::pole(0x8000));
6233  if (arg.data_ & 0x8000)
6234  return half(detail::binary, (arg.data_ <= 0xFC00) ? detail::invalid() : detail::signal(arg.data_));
6235  if (abs >= 0x7C00)
6236  return (abs == 0x7C00) ? arg : half(detail::binary, detail::signal(arg.data_));
6237  for (; abs < 0x400; abs <<= 1, --exp)
6238  ;
6239  exp += abs >> 10;
6240  return half(detail::binary, detail::log2_post<half::round_style, 0xB8AA3B2A>(detail::log2(static_cast<detail::uint32>((abs & 0x3FF) | 0x400) << 20, 27) + 8, exp, 17));
6241 #endif
6242 }
half log(half arg)
Definition: half.hpp:6225

◆ log10

half log10 ( half  arg)
friend

Common logarithm. This function is exact to rounding for all rounding modes.

See also: Documentation for std::log10.

Parameters
argfunction argument
Returns
logarithm of arg to base 10
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN or negative argument
MU_HALF_FE_DIVBYZEROfor 0
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 6253 of file half.hpp.

6254 {
6255 #ifdef HALF_ARITHMETIC_TYPE
6256  return half(detail::binary, detail::float2half<half::round_style>(std::log10(detail::half2float<detail::internal_t>(arg.data_))));
6257 #else
6258  int abs = arg.data_ & 0x7FFF, exp = -15;
6259  if (!abs)
6260  return half(detail::binary, detail::pole(0x8000));
6261  if (arg.data_ & 0x8000)
6262  return half(detail::binary, (arg.data_ <= 0xFC00) ? detail::invalid() : detail::signal(arg.data_));
6263  if (abs >= 0x7C00)
6264  return (abs == 0x7C00) ? arg : half(detail::binary, detail::signal(arg.data_));
6265  switch (abs)
6266  {
6267  case 0x4900:
6268  return half(detail::binary, 0x3C00);
6269  case 0x5640:
6270  return half(detail::binary, 0x4000);
6271  case 0x63D0:
6272  return half(detail::binary, 0x4200);
6273  case 0x70E2:
6274  return half(detail::binary, 0x4400);
6275  }
6276  for (; abs < 0x400; abs <<= 1, --exp)
6277  ;
6278  exp += abs >> 10;
6279  return half(detail::binary, detail::log2_post<half::round_style, 0xD49A784C>(detail::log2(static_cast<detail::uint32>((abs & 0x3FF) | 0x400) << 20, 27) + 8, exp, 16));
6280 #endif
6281 }
half log10(half arg)
Definition: half.hpp:6253

◆ log1p

half log1p ( half  arg)
friend

Natural logarithm plus one. This function may be 1 ULP off the correctly rounded exact result in <0.05% of inputs for std::round_to_nearest and in ~1% of inputs for any other rounding mode.

See also: Documentation for std::log1p.

Parameters
argfunction argument
Returns
logarithm of arg plus 1 to base e
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN or argument <-1
MU_HALF_FE_DIVBYZEROfor -1
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 6337 of file half.hpp.

6338 {
6339 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
6340  return half(detail::binary, detail::float2half<half::round_style>(std::log1p(detail::half2float<detail::internal_t>(arg.data_))));
6341 #else
6342  if (arg.data_ >= 0xBC00)
6343  return half(detail::binary, (arg.data_ == 0xBC00) ? detail::pole(0x8000) : (arg.data_ <= 0xFC00) ? detail::invalid()
6344  : detail::signal(arg.data_));
6345  int abs = arg.data_ & 0x7FFF, exp = -15;
6346  if (!abs || abs >= 0x7C00)
6347  return (abs > 0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
6348  for (; abs < 0x400; abs <<= 1, --exp)
6349  ;
6350  exp += abs >> 10;
6351  detail::uint32 m = static_cast<detail::uint32>((abs & 0x3FF) | 0x400) << 20;
6352  if (arg.data_ & 0x8000)
6353  {
6354  m = 0x40000000 - (m >> -exp);
6355  for (exp = 0; m < 0x40000000; m <<= 1, --exp)
6356  ;
6357  }
6358  else
6359  {
6360  if (exp < 0)
6361  {
6362  m = 0x40000000 + (m >> -exp);
6363  exp = 0;
6364  }
6365  else
6366  {
6367  m += 0x40000000 >> exp;
6368  int i = m >> 31;
6369  m >>= i;
6370  exp += i;
6371  }
6372  }
6373  return half(detail::binary, detail::log2_post<half::round_style, 0xB8AA3B2A>(detail::log2(m), exp, 17));
6374 #endif
6375 }
half log1p(half arg)
Definition: half.hpp:6337

◆ log2

half log2 ( half  arg)
friend

Binary logarithm. This function is exact to rounding for all rounding modes.

See also: Documentation for std::log2.

Parameters
argfunction argument
Returns
logarithm of arg to base 2
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN or negative argument
MU_HALF_FE_DIVBYZEROfor 0
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 6292 of file half.hpp.

6293 {
6294 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
6295  return half(detail::binary, detail::float2half<half::round_style>(std::log2(detail::half2float<detail::internal_t>(arg.data_))));
6296 #else
6297  int abs = arg.data_ & 0x7FFF, exp = -15, s = 0;
6298  if (!abs)
6299  return half(detail::binary, detail::pole(0x8000));
6300  if (arg.data_ & 0x8000)
6301  return half(detail::binary, (arg.data_ <= 0xFC00) ? detail::invalid() : detail::signal(arg.data_));
6302  if (abs >= 0x7C00)
6303  return (abs == 0x7C00) ? arg : half(detail::binary, detail::signal(arg.data_));
6304  if (abs == 0x3C00)
6305  return half(detail::binary, 0);
6306  for (; abs < 0x400; abs <<= 1, --exp)
6307  ;
6308  exp += (abs >> 10);
6309  if (!(abs & 0x3FF))
6310  {
6311  unsigned int value = static_cast<unsigned>(exp < 0) << 15, m = std::abs(exp) << 6;
6312  for (exp = 18; m < 0x400; m <<= 1, --exp)
6313  ;
6314  return half(detail::binary, value + (exp << 10) + m);
6315  }
6316  detail::uint32 ilog = exp, sign = detail::sign_mask(ilog), m = (((ilog << 27) + (detail::log2(static_cast<detail::uint32>((abs & 0x3FF) | 0x400) << 20, 28) >> 4)) ^ sign) - sign;
6317  if (!m)
6318  return half(detail::binary, 0);
6319  for (exp = 14; m < 0x8000000 && exp; m <<= 1, --exp)
6320  ;
6321  for (; m > 0xFFFFFFF; m >>= 1, ++exp)
6322  s |= m & 1;
6323  return half(detail::binary, detail::fixed2half<half::round_style, 27, false, false, true>(m, exp, sign & 0x8000, s));
6324 #endif
6325 }
half log2(half arg)
Definition: half.hpp:6292

◆ logb

half logb ( half  arg)
friend

Extract exponent. See also: Documentation for std::logb.

Parameters
argnumber to query
Returns
floating-point exponent
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN
MU_HALF_FE_DIVBYZEROfor 0

Definition at line 7525 of file half.hpp.

7526 {
7527  int abs = arg.data_ & 0x7FFF, exp;
7528  if (!abs)
7529  return half(detail::binary, detail::pole(0x8000));
7530  if (abs >= 0x7C00)
7531  return half(detail::binary, (abs == 0x7C00) ? 0x7C00 : detail::signal(arg.data_));
7532  for (exp = (abs >> 10) - 15; abs < 0x200; abs <<= 1, --exp)
7533  ;
7534  unsigned int value = static_cast<unsigned>(exp < 0) << 15;
7535  if (exp)
7536  {
7537  unsigned int m = std::abs(exp) << 6;
7538  for (exp = 18; m < 0x400; m <<= 1, --exp)
7539  ;
7540  value |= (exp << 10) + m;
7541  }
7542  return half(detail::binary, value);
7543 }

◆ lrint

long lrint ( half  arg)
friend

Nearest integer using half's internal rounding mode. See also: Documentation for std::lrint.

Parameters
arghalf expression to round
Returns
nearest integer using default rounding mode
Exceptions
MU_HALF_FE_INVALIDif value is not representable as long
MU_HALF_FE_INEXACTif value had to be rounded

Definition at line 7355 of file half.hpp.

7356 {
7357  return detail::half2int<half::round_style, true, true, long>(arg.data_);
7358 }

◆ lround

long lround ( half  arg)
friend

Nearest integer. See also: Documentation for std::lround.

Parameters
arghalf to round
Returns
nearest integer, rounded away from zero in half-way cases
Exceptions
MU_HALF_FE_INVALIDif value is not representable as long

Definition at line 7333 of file half.hpp.

7334 {
7335  return detail::half2int<std::round_to_nearest, false, false, long>(arg.data_);
7336 }

◆ modf

half modf ( half  arg,
half iptr 
)
friend

Extract integer and fractional parts. See also: Documentation for std::modf.

Parameters
argnumber to decompress
iptraddress to store integer part at
Returns
fractional part
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN

Definition at line 7476 of file half.hpp.

7477 {
7478  unsigned int abs = arg.data_ & 0x7FFF;
7479  if (abs > 0x7C00)
7480  {
7481  arg = half(detail::binary, detail::signal(arg.data_));
7482  return *iptr = arg, arg;
7483  }
7484  if (abs >= 0x6400)
7485  return *iptr = arg, half(detail::binary, arg.data_ & 0x8000);
7486  if (abs < 0x3C00)
7487  return iptr->data_ = arg.data_ & 0x8000, arg;
7488  unsigned int exp = abs >> 10, mask = (1 << (25 - exp)) - 1, m = arg.data_ & mask;
7489  iptr->data_ = arg.data_ & ~mask;
7490  if (!m)
7491  return half(detail::binary, arg.data_ & 0x8000);
7492  for (; m < 0x400; m <<= 1, --exp)
7493  ;
7494  return half(detail::binary, (arg.data_ & 0x8000) | (exp << 10) | (m & 0x3FF));
7495 }

◆ nanh

half nanh ( const char *  arg)
friend

Get NaN value. See also: Documentation for std::nan.

Parameters
argstring code
Returns
quiet NaN

Definition at line 6090 of file half.hpp.

6091 {
6092  unsigned int value = 0x7FFF;
6093  while (*arg)
6094  value ^= static_cast<unsigned>(*arg++) & 0xFF;
6095  return half(detail::binary, value);
6096 }

◆ nearbyint

half nearbyint ( half  arg)
friend

Nearest integer using half's internal rounding mode. See also: Documentation for std::nearbyint.

Parameters
arghalf expression to round
Returns
nearest integer using default rounding mode
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN

Definition at line 7365 of file half.hpp.

7366 {
7367  return half(detail::binary, detail::integral<half::round_style, true, false>(arg.data_));
7368 }

◆ nextafter

half nextafter ( half  from,
half  to 
)
friend

Next representable value. See also: Documentation for std::nextafter.

Parameters
fromvalue to compute next representable value for
todirection towards which to compute next value
Returns
next representable value after from in direction towards to
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN
MU_HALF_FE_OVERFLOWfor infinite result from finite argument
MU_HALF_FE_UNDERFLOWfor subnormal result

Definition at line 7553 of file half.hpp.

7554 {
7555  int fabs = from.data_ & 0x7FFF, tabs = to.data_ & 0x7FFF;
7556  if (fabs > 0x7C00 || tabs > 0x7C00)
7557  return half(detail::binary, detail::signal(from.data_, to.data_));
7558  if (from.data_ == to.data_ || !(fabs | tabs))
7559  return to;
7560  if (!fabs)
7561  {
7563  return half(detail::binary, (to.data_ & 0x8000) + 1);
7564  }
7565  unsigned int out = from.data_ + (((from.data_ >> 15) ^ static_cast<unsigned>((from.data_ ^ (0x8000 | (0x8000 - (from.data_ >> 15)))) < (to.data_ ^ (0x8000 | (0x8000 - (to.data_ >> 15)))))) << 1) - 1;
7566  detail::raise(MU_HALF_FE_OVERFLOW, fabs < 0x7C00 && (out & 0x7C00) == 0x7C00);
7568  return half(detail::binary, out);
7569 }
friend HALF_CONSTEXPR half fabs(half)
Definition: half.hpp:5896
#define MU_HALF_FE_UNDERFLOW
Definition: half.hpp:44
#define MU_HALF_FE_OVERFLOW
Definition: half.hpp:43
#define HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT
Definition: half.hpp:377

◆ nexttoward

half nexttoward ( half  from,
long double  to 
)
friend

Next representable value. See also: Documentation for std::nexttoward.

Parameters
fromvalue to compute next representable value for
todirection towards which to compute next value
Returns
next representable value after from in direction towards to
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN
MU_HALF_FE_OVERFLOWfor infinite result from finite argument
MU_HALF_FE_UNDERFLOWfor subnormal result

Definition at line 7579 of file half.hpp.

7580 {
7581  int fabs = from.data_ & 0x7FFF;
7582  if (fabs > 0x7C00)
7583  return half(detail::binary, detail::signal(from.data_));
7584  long double lfrom = static_cast<long double>(from);
7585  if (detail::builtin_isnan(to) || lfrom == to)
7586  return half(static_cast<float>(to));
7587  if (!fabs)
7588  {
7590  return half(detail::binary, (static_cast<unsigned>(detail::builtin_signbit(to)) << 15) + 1);
7591  }
7592  unsigned int out = from.data_ + (((from.data_ >> 15) ^ static_cast<unsigned>(lfrom < to)) << 1) - 1;
7593  detail::raise(MU_HALF_FE_OVERFLOW, (out & 0x7FFF) == 0x7C00);
7595  return half(detail::binary, out);
7596 }
bool builtin_signbit(T arg)
Definition: half.hpp:680
bool builtin_isnan(T arg)
Definition: half.hpp:663

◆ operator!=

HALF_CONSTEXPR_NOERR bool operator!= ( half  x,
half  y 
)
friend

Comparison for inequality.

Parameters
xfirst operand
ysecond operand
Return values
trueif operands not equal
falseelse
Exceptions
MU_HALF_FE_INVALIDif x or y is NaN

Definition at line 5630 of file half.hpp.

5631 {
5632  return detail::compsignal(x.data_, y.data_) || (x.data_ != y.data_ && ((x.data_ | y.data_) & 0x7FFF));
5633 }
HALF_CONSTEXPR_NOERR bool compsignal(unsigned int x, unsigned int y)
Definition: half.hpp:785

◆ operator*

half operator* ( half  x,
half  y 
)
friend

Multiplication. This operation is exact to rounding for all rounding modes.

Parameters
xleft operand
yright operand
Returns
product of half expressions
Exceptions
MU_HALF_FE_INVALIDif multiplying 0 with infinity or if x or y is signaling NaN
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 5779 of file half.hpp.

5780 {
5781 #ifdef HALF_ARITHMETIC_TYPE
5782  return half(detail::binary, detail::float2half<half::round_style>(detail::half2float<detail::internal_t>(x.data_) * detail::half2float<detail::internal_t>(y.data_)));
5783 #else
5784  int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, exp = -16;
5785  unsigned int sign = (x.data_ ^ y.data_) & 0x8000;
5786  if (absx >= 0x7C00 || absy >= 0x7C00)
5787  return half(detail::binary, (absx > 0x7C00 || absy > 0x7C00) ? detail::signal(x.data_, y.data_) : ((absx == 0x7C00 && !absy) || (absy == 0x7C00 && !absx)) ? detail::invalid()
5788  : (sign | 0x7C00));
5789  if (!absx || !absy)
5790  return half(detail::binary, sign);
5791  for (; absx < 0x400; absx <<= 1, --exp)
5792  ;
5793  for (; absy < 0x400; absy <<= 1, --exp)
5794  ;
5795  detail::uint32 m = static_cast<detail::uint32>((absx & 0x3FF) | 0x400) * static_cast<detail::uint32>((absy & 0x3FF) | 0x400);
5796  int i = m >> 21, s = m & i;
5797  exp += (absx >> 10) + (absy >> 10) + i;
5798  if (exp > 29)
5799  return half(detail::binary, detail::overflow<half::round_style>(sign));
5800  else if (exp < -11)
5801  return half(detail::binary, detail::underflow<half::round_style>(sign));
5802  return half(detail::binary, detail::fixed2half<half::round_style, 20, false, false, false>(m >> i, exp, sign, s));
5803 #endif
5804 }

◆ operator+

half operator+ ( half  x,
half  y 
)
friend

Addition. This operation is exact to rounding for all rounding modes.

Parameters
xleft operand
yright operand
Returns
sum of half expressions
Exceptions
MU_HALF_FE_INVALIDif x and y are infinities with different signs or signaling NaNs
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 5711 of file half.hpp.

5712 {
5713 #ifdef HALF_ARITHMETIC_TYPE
5714  return half(detail::binary, detail::float2half<half::round_style>(detail::half2float<detail::internal_t>(x.data_) + detail::half2float<detail::internal_t>(y.data_)));
5715 #else
5716  int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF;
5717  bool sub = ((x.data_ ^ y.data_) & 0x8000) != 0;
5718  if (absx >= 0x7C00 || absy >= 0x7C00)
5719  return half(detail::binary, (absx > 0x7C00 || absy > 0x7C00) ? detail::signal(x.data_, y.data_) : (absy != 0x7C00) ? x.data_
5720  : (sub && absx == 0x7C00) ? detail::invalid()
5721  : y.data_);
5722  if (!absx)
5723  return absy ? y : half(detail::binary, (half::round_style == std::round_toward_neg_infinity) ? (x.data_ | y.data_) : (x.data_ & y.data_));
5724  if (!absy)
5725  return x;
5726  unsigned int sign = ((sub && absy > absx) ? y.data_ : x.data_) & 0x8000;
5727  if (absy > absx)
5728  std::swap(absx, absy);
5729  int exp = (absx >> 10) + (absx <= 0x3FF), d = exp - (absy >> 10) - (absy <= 0x3FF), mx = ((absx & 0x3FF) | ((absx > 0x3FF) << 10)) << 3, my;
5730  if (d < 13)
5731  {
5732  my = ((absy & 0x3FF) | ((absy > 0x3FF) << 10)) << 3;
5733  my = (my >> d) | ((my & ((1 << d) - 1)) != 0);
5734  }
5735  else
5736  my = 1;
5737  if (sub)
5738  {
5739  if (!(mx -= my))
5740  return half(detail::binary, static_cast<unsigned>(half::round_style == std::round_toward_neg_infinity) << 15);
5741  for (; mx < 0x2000 && exp > 1; mx <<= 1, --exp)
5742  ;
5743  }
5744  else
5745  {
5746  mx += my;
5747  int i = mx >> 14;
5748  if ((exp += i) > 30)
5749  return half(detail::binary, detail::overflow<half::round_style>(sign));
5750  mx = (mx >> i) | (mx & i);
5751  }
5752  return half(detail::binary, detail::rounded<half::round_style, false>(sign + ((exp - 1) << 10) + (mx >> 3), (mx >> 2) & 1, (mx & 0x3) != 0));
5753 #endif
5754 }

◆ operator- [1/2]

HALF_CONSTEXPR half operator- ( half  arg)
friend

Negation.

Parameters
argoperand
Returns
negated operand

Definition at line 5699 of file half.hpp.

5700 {
5701  return half(detail::binary, arg.data_ ^ 0x8000);
5702 }

◆ operator- [2/2]

half operator- ( half  x,
half  y 
)
friend

Subtraction. This operation is exact to rounding for all rounding modes.

Parameters
xleft operand
yright operand
Returns
difference of half expressions
Exceptions
MU_HALF_FE_INVALIDif x and y are infinities with equal signs or signaling NaNs
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 5763 of file half.hpp.

5764 {
5765 #ifdef HALF_ARITHMETIC_TYPE
5766  return half(detail::binary, detail::float2half<half::round_style>(detail::half2float<detail::internal_t>(x.data_) - detail::half2float<detail::internal_t>(y.data_)));
5767 #else
5768  return x + -y;
5769 #endif
5770 }

◆ operator/

half operator/ ( half  x,
half  y 
)
friend

Division. This operation is exact to rounding for all rounding modes.

Parameters
xleft operand
yright operand
Returns
quotient of half expressions
Exceptions
MU_HALF_FE_INVALIDif dividing 0s or infinities with each other or if x or y is signaling NaN
MU_HALF_FE_DIVBYZEROif dividing finite value by 0
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 5814 of file half.hpp.

5815 {
5816 #ifdef HALF_ARITHMETIC_TYPE
5817  return half(detail::binary, detail::float2half<half::round_style>(detail::half2float<detail::internal_t>(x.data_) / detail::half2float<detail::internal_t>(y.data_)));
5818 #else
5819  int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, exp = 14;
5820  unsigned int sign = (x.data_ ^ y.data_) & 0x8000;
5821  if (absx >= 0x7C00 || absy >= 0x7C00)
5822  return half(detail::binary, (absx > 0x7C00 || absy > 0x7C00) ? detail::signal(x.data_, y.data_) : (absx == absy) ? detail::invalid()
5823  : (sign | ((absx == 0x7C00) ? 0x7C00 : 0)));
5824  if (!absx)
5825  return half(detail::binary, absy ? sign : detail::invalid());
5826  if (!absy)
5827  return half(detail::binary, detail::pole(sign));
5828  for (; absx < 0x400; absx <<= 1, --exp)
5829  ;
5830  for (; absy < 0x400; absy <<= 1, ++exp)
5831  ;
5832  detail::uint32 mx = (absx & 0x3FF) | 0x400, my = (absy & 0x3FF) | 0x400;
5833  int i = mx < my;
5834  exp += (absx >> 10) - (absy >> 10) - i;
5835  if (exp > 29)
5836  return half(detail::binary, detail::overflow<half::round_style>(sign));
5837  else if (exp < -11)
5838  return half(detail::binary, detail::underflow<half::round_style>(sign));
5839  mx <<= 12 + i;
5840  my <<= 1;
5841  return half(detail::binary, detail::fixed2half<half::round_style, 11, false, false, false>(mx / my, exp, sign, mx % my != 0));
5842 #endif
5843 }

◆ operator<

HALF_CONSTEXPR_NOERR bool operator< ( half  x,
half  y 
)
friend

Comparison for less than.

Parameters
xfirst operand
ysecond operand
Return values
trueif x less than y
falseelse
Exceptions
MU_HALF_FE_INVALIDif x or y is NaN

Definition at line 5641 of file half.hpp.

5642 {
5643  return !detail::compsignal(x.data_, y.data_) &&
5644  ((x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) + (x.data_ >> 15)) < ((y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) + (y.data_ >> 15));
5645 }

◆ operator<=

HALF_CONSTEXPR_NOERR bool operator<= ( half  x,
half  y 
)
friend

Comparison for less equal.

Parameters
xfirst operand
ysecond operand
Return values
trueif x less equal y
falseelse
Exceptions
MU_HALF_FE_INVALIDif x or y is NaN

Definition at line 5665 of file half.hpp.

5666 {
5667  return !detail::compsignal(x.data_, y.data_) &&
5668  ((x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) + (x.data_ >> 15)) <= ((y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) + (y.data_ >> 15));
5669 }

◆ operator==

HALF_CONSTEXPR_NOERR bool operator== ( half  x,
half  y 
)
friend

Comparison for equality.

Parameters
xfirst operand
ysecond operand
Return values
trueif operands equal
falseelse
Exceptions
MU_HALF_FE_INVALIDif x or y is NaN

Definition at line 5619 of file half.hpp.

5620 {
5621  return !detail::compsignal(x.data_, y.data_) && (x.data_ == y.data_ || !((x.data_ | y.data_) & 0x7FFF));
5622 }

◆ operator>

HALF_CONSTEXPR_NOERR bool operator> ( half  x,
half  y 
)
friend

Comparison for greater than.

Parameters
xfirst operand
ysecond operand
Return values
trueif x greater than y
falseelse
Exceptions
MU_HALF_FE_INVALIDif x or y is NaN

Definition at line 5653 of file half.hpp.

5654 {
5655  return !detail::compsignal(x.data_, y.data_) &&
5656  ((x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) + (x.data_ >> 15)) > ((y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) + (y.data_ >> 15));
5657 }

◆ operator>=

HALF_CONSTEXPR_NOERR bool operator>= ( half  x,
half  y 
)
friend

Comparison for greater equal.

Parameters
xfirst operand
ysecond operand
Return values
trueif x greater equal y
falseelse
Exceptions
MU_HALF_FE_INVALIDif x or y is NaN

Definition at line 5677 of file half.hpp.

5678 {
5679  return !detail::compsignal(x.data_, y.data_) &&
5680  ((x.data_ ^ (0x8000 | (0x8000 - (x.data_ >> 15)))) + (x.data_ >> 15)) >= ((y.data_ ^ (0x8000 | (0x8000 - (y.data_ >> 15)))) + (y.data_ >> 15));
5681 }

◆ pow

half pow ( half  x,
half  y 
)
friend

Power function. This function may be 1 ULP off the correctly rounded exact result for any rounding mode in ~0.00025% of inputs.

See also: Documentation for std::pow.

Parameters
xbase
yexponent
Returns
x raised to y
Exceptions
MU_HALF_FE_INVALIDif x or y is signaling NaN or if x is finite an negative and y is finite and not integral
MU_HALF_FE_DIVBYZEROif x is 0 and y is negative
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 6620 of file half.hpp.

6621 {
6622 #ifdef HALF_ARITHMETIC_TYPE
6623  return half(detail::binary, detail::float2half<half::round_style>(std::pow(detail::half2float<detail::internal_t>(x.data_), detail::half2float<detail::internal_t>(y.data_))));
6624 #else
6625  int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, exp = -15;
6626  if (!absy || x.data_ == 0x3C00)
6627  return half(detail::binary, detail::select(0x3C00, (x.data_ == 0x3C00) ? y.data_ : x.data_));
6628  bool is_int = absy >= 0x6400 || (absy >= 0x3C00 && !(absy & ((1 << (25 - (absy >> 10))) - 1)));
6629  unsigned int sign = x.data_ & (static_cast<unsigned>((absy < 0x6800) && is_int && ((absy >> (25 - (absy >> 10))) & 1)) << 15);
6630  if (absx >= 0x7C00 || absy >= 0x7C00)
6631  return half(detail::binary, (absx > 0x7C00 || absy > 0x7C00) ? detail::signal(x.data_, y.data_) : (absy == 0x7C00) ? ((absx == 0x3C00) ? 0x3C00 : (!absx && y.data_ == 0xFC00) ? detail::pole()
6632  : (0x7C00 & -((y.data_ >> 15) ^ (absx > 0x3C00))))
6633  : (sign | (0x7C00 & ((y.data_ >> 15) - 1U))));
6634  if (!absx)
6635  return half(detail::binary, (y.data_ & 0x8000) ? detail::pole(sign) : sign);
6636  if ((x.data_ & 0x8000) && !is_int)
6637  return half(detail::binary, detail::invalid());
6638  if (x.data_ == 0xBC00)
6639  return half(detail::binary, sign | 0x3C00);
6640  switch (y.data_)
6641  {
6642  case 0x3800:
6643  return sqrt(x);
6644  case 0x3C00:
6645  return half(detail::binary, detail::check_underflow(x.data_));
6646  case 0x4000:
6647  return x * x;
6648  case 0xBC00:
6649  return half(detail::binary, 0x3C00) / x;
6650  }
6651  for (; absx < 0x400; absx <<= 1, --exp)
6652  ;
6653  detail::uint32 ilog = exp + (absx >> 10), msign = detail::sign_mask(ilog), f, m = (((ilog << 27) + ((detail::log2(static_cast<detail::uint32>((absx & 0x3FF) | 0x400) << 20) + 8) >> 4)) ^ msign) - msign;
6654  for (exp = -11; m < 0x80000000; m <<= 1, --exp)
6655  ;
6656  for (; absy < 0x400; absy <<= 1, --exp)
6657  ;
6658  m = detail::multiply64(m, static_cast<detail::uint32>((absy & 0x3FF) | 0x400) << 21);
6659  int i = m >> 31;
6660  exp += (absy >> 10) + i;
6661  m <<= 1 - i;
6662  if (exp < 0)
6663  {
6664  f = m >> -exp;
6665  exp = 0;
6666  }
6667  else
6668  {
6669  f = (m << exp) & 0x7FFFFFFF;
6670  exp = m >> (31 - exp);
6671  }
6672  return half(detail::binary, detail::exp2_post<half::round_style>(f, exp, ((msign & 1) ^ (y.data_ >> 15)) != 0, sign));
6673 #endif
6674 }
friend half sqrt(half)
Definition: half.hpp:6390
half pow(half x, half y)
Definition: half.hpp:6620

◆ remainder

half remainder ( half  x,
half  y 
)
friend

Remainder of division. See also: Documentation for std::remainder.

Parameters
xfirst operand
ysecond operand
Returns
remainder of floating-point division.
Exceptions
MU_HALF_FE_INVALIDif x is infinite or y is 0 or if x or y is signaling NaN

Definition at line 5937 of file half.hpp.

5938 {
5939  unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, sign = x.data_ & 0x8000;
5940  if (absx >= 0x7C00 || absy >= 0x7C00)
5941  return half(detail::binary, (absx > 0x7C00 || absy > 0x7C00) ? detail::signal(x.data_, y.data_) : (absx == 0x7C00) ? detail::invalid()
5942  : x.data_);
5943  if (!absy)
5944  return half(detail::binary, detail::invalid());
5945  if (absx == absy)
5946  return half(detail::binary, sign);
5947  return half(detail::binary, sign ^ detail::mod<false, true>(absx, absy));
5948 }

◆ remquo

half remquo ( half  x,
half  y,
int *  quo 
)
friend

Remainder of division. See also: Documentation for std::remquo.

Parameters
xfirst operand
ysecond operand
quoaddress to store some bits of quotient at
Returns
remainder of floating-point division.
Exceptions
MU_HALF_FE_INVALIDif x is infinite or y is 0 or if x or y is signaling NaN

Definition at line 5957 of file half.hpp.

5958 {
5959  unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, value = x.data_ & 0x8000;
5960  if (absx >= 0x7C00 || absy >= 0x7C00)
5961  return half(detail::binary, (absx > 0x7C00 || absy > 0x7C00) ? detail::signal(x.data_, y.data_) : (absx == 0x7C00) ? detail::invalid()
5962  : (*quo = 0, x.data_));
5963  if (!absy)
5964  return half(detail::binary, detail::invalid());
5965  bool qsign = ((value ^ y.data_) & 0x8000) != 0;
5966  int q = 1;
5967  if (absx != absy)
5968  value ^= detail::mod<true, true>(absx, absy, &q);
5969  return *quo = qsign ? -q : q, half(detail::binary, value);
5970 }

◆ rint

half rint ( half  arg)
friend

Nearest integer using half's internal rounding mode. See also: Documentation for std::rint.

Parameters
arghalf expression to round
Returns
nearest integer using default rounding mode
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN
MU_HALF_FE_INEXACTif value had to be rounded

Definition at line 7344 of file half.hpp.

7345 {
7346  return half(detail::binary, detail::integral<half::round_style, true, true>(arg.data_));
7347 }

◆ round

half round ( half  arg)
friend

Nearest integer. See also: Documentation for std::round.

Parameters
arghalf to round
Returns
nearest integer, rounded away from zero in half-way cases
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN
MU_HALF_FE_INEXACTif value had to be rounded

Definition at line 7323 of file half.hpp.

7324 {
7325  return half(detail::binary, detail::integral<std::round_to_nearest, false, true>(arg.data_));
7326 }

◆ rsqrt

half rsqrt ( half  arg)
friend

Inverse square root. This function is exact to rounding for all rounding modes and thus generally more accurate than directly computing 1 / sqrt(arg) in half-precision, in addition to also being faster.

Parameters
argfunction argument
Returns
reciprocal of square root of arg
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN and negative arguments
MU_HALF_FE_INEXACTaccording to rounding

Definition at line 6413 of file half.hpp.

6414 {
6415 #ifdef HALF_ARITHMETIC_TYPE
6416  return half(detail::binary, detail::float2half<half::round_style>(detail::internal_t(1) / std::sqrt(detail::half2float<detail::internal_t>(arg.data_))));
6417 #else
6418  unsigned int abs = arg.data_ & 0x7FFF, bias = 0x4000;
6419  if (!abs || arg.data_ >= 0x7C00)
6420  return half(detail::binary, (abs > 0x7C00) ? detail::signal(arg.data_) : (arg.data_ > 0x8000) ? detail::invalid()
6421  : !abs ? detail::pole(arg.data_ & 0x8000)
6422  : 0);
6423  for (; abs < 0x400; abs <<= 1, bias -= 0x400)
6424  ;
6425  unsigned int frac = (abs += bias) & 0x7FF;
6426  if (frac == 0x400)
6427  return half(detail::binary, 0x7A00 - (abs >> 1));
6428  if ((half::round_style == std::round_to_nearest && (frac == 0x3FE || frac == 0x76C)) ||
6429  (half::round_style != std::round_to_nearest && (frac == 0x15A || frac == 0x3FC || frac == 0x401 || frac == 0x402 || frac == 0x67B)))
6430  return pow(arg, half(detail::binary, 0xB800));
6431  detail::uint32 f = 0x17376 - abs, mx = (abs & 0x3FF) | 0x400, my = ((f >> 1) & 0x3FF) | 0x400, mz = my * my;
6432  int expy = (f >> 11) - 31, expx = 32 - (abs >> 10), i = mz >> 21;
6433  for (mz = 0x60000000 - (((mz >> i) * mx) >> (expx - 2 * expy - i)); mz < 0x40000000; mz <<= 1, --expy)
6434  ;
6435  i = (my *= mz >> 10) >> 31;
6436  expy += i;
6437  my = (my >> (20 + i)) + 1;
6438  i = (mz = my * my) >> 21;
6439  for (mz = 0x60000000 - (((mz >> i) * mx) >> (expx - 2 * expy - i)); mz < 0x40000000; mz <<= 1, --expy)
6440  ;
6441  i = (my *= (mz >> 10) + 1) >> 31;
6442  return half(detail::binary, detail::fixed2half<half::round_style, 30, false, false, true>(my >> i, expy + i + 14));
6443 #endif
6444 }
friend half pow(half, half)
Definition: half.hpp:6620

◆ scalbln

half scalbln ( half  arg,
long  exp 
)
friend

Multiply by power of two. This function is exact to rounding for all rounding modes.

See also: Documentation for std::scalbln.

Parameters
argnumber to modify
exppower of two to multiply with
Returns
arg multplied by 2 raised to exp
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 7424 of file half.hpp.

7425 {
7426  unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000;
7427  if (abs >= 0x7C00 || !abs)
7428  return (abs > 0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
7429  for (; abs < 0x400; abs <<= 1, --exp)
7430  ;
7431  exp += abs >> 10;
7432  if (exp > 30)
7433  return half(detail::binary, detail::overflow<half::round_style>(sign));
7434  else if (exp < -10)
7435  return half(detail::binary, detail::underflow<half::round_style>(sign));
7436  else if (exp > 0)
7437  return half(detail::binary, sign | (exp << 10) | (abs & 0x3FF));
7438  unsigned int m = (abs & 0x3FF) | 0x400;
7439  return half(detail::binary, detail::rounded<half::round_style, false>(sign | (m >> (1 - exp)), (m >> -exp) & 1, (m & ((1 << -exp) - 1)) != 0));
7440 }

◆ signbit

HALF_CONSTEXPR bool signbit ( half  arg)
friend

Check sign. See also: Documentation for std::signbit.

Parameters
argnumber to check
Return values
truefor negative number
falsefor positive number

Definition at line 7674 of file half.hpp.

7675 {
7676  return (arg.data_ & 0x8000) != 0;
7677 }

◆ sin

half sin ( half  arg)
friend

Sine function. This function is exact to rounding for all rounding modes.

See also: Documentation for std::sin.

Parameters
argfunction argument
Returns
sine value of arg
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN or infinity
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 6761 of file half.hpp.

6762 {
6763 #ifdef HALF_ARITHMETIC_TYPE
6764  return half(detail::binary, detail::float2half<half::round_style>(std::sin(detail::half2float<detail::internal_t>(arg.data_))));
6765 #else
6766  int abs = arg.data_ & 0x7FFF, k;
6767  if (!abs)
6768  return arg;
6769  if (abs >= 0x7C00)
6770  return half(detail::binary, (abs == 0x7C00) ? detail::invalid() : detail::signal(arg.data_));
6771  if (abs < 0x2900)
6772  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_ - 1, 1, 1));
6773  if (half::round_style != std::round_to_nearest)
6774  switch (abs)
6775  {
6776  case 0x48B7:
6777  return half(detail::binary, detail::rounded<half::round_style, true>((~arg.data_ & 0x8000) | 0x1D07, 1, 1));
6778  case 0x6A64:
6779  return half(detail::binary, detail::rounded<half::round_style, true>((~arg.data_ & 0x8000) | 0x3BFE, 1, 1));
6780  case 0x6D8C:
6781  return half(detail::binary, detail::rounded<half::round_style, true>((arg.data_ & 0x8000) | 0x0FE6, 1, 1));
6782  }
6783  std::pair<detail::uint32, detail::uint32> sc = detail::sincos(detail::angle_arg(abs, k), 28);
6784  detail::uint32 sign = -static_cast<detail::uint32>(((k >> 1) & 1) ^ (arg.data_ >> 15));
6785  return half(detail::binary, detail::fixed2half<half::round_style, 30, true, true, true>((((k & 1) ? sc.second : sc.first) ^ sign) - sign));
6786 #endif
6787 }
half sin(half arg)
Definition: half.hpp:6761

◆ sincos

void sincos ( half  arg,
half sin,
half cos 
)
friend

Compute sine and cosine simultaneously. This returns the same results as sin() and cos() but is faster than calling each function individually.

This function is exact to rounding for all rounding modes.

Parameters
argfunction argument
sinvariable to take sine of arg
cosvariable to take cosine of arg
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN or infinity
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 6690 of file half.hpp.

6691 {
6692 #ifdef HALF_ARITHMETIC_TYPE
6693  detail::internal_t f = detail::half2float<detail::internal_t>(arg.data_);
6694  *sin = half(detail::binary, detail::float2half<half::round_style>(std::sin(f)));
6695  *cos = half(detail::binary, detail::float2half<half::round_style>(std::cos(f)));
6696 #else
6697  int abs = arg.data_ & 0x7FFF, sign = arg.data_ >> 15, k;
6698  if (abs >= 0x7C00)
6699  *sin = *cos = half(detail::binary, (abs == 0x7C00) ? detail::invalid() : detail::signal(arg.data_));
6700  else if (!abs)
6701  {
6702  *sin = arg;
6703  *cos = half(detail::binary, 0x3C00);
6704  }
6705  else if (abs < 0x2500)
6706  {
6707  *sin = half(detail::binary, detail::rounded<half::round_style, true>(arg.data_ - 1, 1, 1));
6708  *cos = half(detail::binary, detail::rounded<half::round_style, true>(0x3BFF, 1, 1));
6709  }
6710  else
6711  {
6712  if (half::round_style != std::round_to_nearest)
6713  {
6714  switch (abs)
6715  {
6716  case 0x48B7:
6717  *sin = half(detail::binary, detail::rounded<half::round_style, true>((~arg.data_ & 0x8000) | 0x1D07, 1, 1));
6718  *cos = half(detail::binary, detail::rounded<half::round_style, true>(0xBBFF, 1, 1));
6719  return;
6720  case 0x598C:
6721  *sin = half(detail::binary, detail::rounded<half::round_style, true>((arg.data_ & 0x8000) | 0x3BFF, 1, 1));
6722  *cos = half(detail::binary, detail::rounded<half::round_style, true>(0x80FC, 1, 1));
6723  return;
6724  case 0x6A64:
6725  *sin = half(detail::binary, detail::rounded<half::round_style, true>((~arg.data_ & 0x8000) | 0x3BFE, 1, 1));
6726  *cos = half(detail::binary, detail::rounded<half::round_style, true>(0x27FF, 1, 1));
6727  return;
6728  case 0x6D8C:
6729  *sin = half(detail::binary, detail::rounded<half::round_style, true>((arg.data_ & 0x8000) | 0x0FE6, 1, 1));
6730  *cos = half(detail::binary, detail::rounded<half::round_style, true>(0x3BFF, 1, 1));
6731  return;
6732  }
6733  }
6734  std::pair<detail::uint32, detail::uint32> sc = detail::sincos(detail::angle_arg(abs, k), 28);
6735  switch (k & 3)
6736  {
6737  case 1:
6738  sc = std::make_pair(sc.second, -sc.first);
6739  break;
6740  case 2:
6741  sc = std::make_pair(-sc.first, -sc.second);
6742  break;
6743  case 3:
6744  sc = std::make_pair(-sc.second, sc.first);
6745  break;
6746  }
6747  *sin = half(detail::binary, detail::fixed2half<half::round_style, 30, true, true, true>((sc.first ^ -static_cast<detail::uint32>(sign)) + sign));
6748  *cos = half(detail::binary, detail::fixed2half<half::round_style, 30, true, true, true>(sc.second));
6749  }
6750 #endif
6751 }
friend half sin(half)
Definition: half.hpp:6761
friend half cos(half)
Definition: half.hpp:6797

◆ sinh

half sinh ( half  arg)
friend

Hyperbolic sine. This function is exact to rounding for all rounding modes.

See also: Documentation for std::sinh.

Parameters
argfunction argument
Returns
hyperbolic sine value of arg
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 7007 of file half.hpp.

7008 {
7009 #ifdef HALF_ARITHMETIC_TYPE
7010  return half(detail::binary, detail::float2half<half::round_style>(std::sinh(detail::half2float<detail::internal_t>(arg.data_))));
7011 #else
7012  int abs = arg.data_ & 0x7FFF, exp;
7013  if (!abs || abs >= 0x7C00)
7014  return (abs > 0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
7015  if (abs <= 0x2900)
7016  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_, 0, 1));
7017  std::pair<detail::uint32, detail::uint32> mm = detail::hyperbolic_args(abs, exp, (half::round_style == std::round_to_nearest) ? 29 : 27);
7018  detail::uint32 m = mm.first - mm.second;
7019  for (exp += 13; m < 0x80000000 && exp; m <<= 1, --exp)
7020  ;
7021  unsigned int sign = arg.data_ & 0x8000;
7022  if (exp > 29)
7023  return half(detail::binary, detail::overflow<half::round_style>(sign));
7024  return half(detail::binary, detail::fixed2half<half::round_style, 31, false, false, true>(m, exp, sign));
7025 #endif
7026 }
half sinh(half arg)
Definition: half.hpp:7007

◆ sqrt

half sqrt ( half  arg)
friend

Square root. This function is exact to rounding for all rounding modes.

See also: Documentation for std::sqrt.

Parameters
argfunction argument
Returns
square root of arg
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN and negative arguments
MU_HALF_FE_INEXACTaccording to rounding

Definition at line 6390 of file half.hpp.

6391 {
6392 #ifdef HALF_ARITHMETIC_TYPE
6393  return half(detail::binary, detail::float2half<half::round_style>(std::sqrt(detail::half2float<detail::internal_t>(arg.data_))));
6394 #else
6395  int abs = arg.data_ & 0x7FFF, exp = 15;
6396  if (!abs || arg.data_ >= 0x7C00)
6397  return half(detail::binary, (abs > 0x7C00) ? detail::signal(arg.data_) : (arg.data_ > 0x8000) ? detail::invalid()
6398  : arg.data_);
6399  for (; abs < 0x400; abs <<= 1, --exp)
6400  ;
6401  detail::uint32 r = static_cast<detail::uint32>((abs & 0x3FF) | 0x400) << 10, m = detail::sqrt<20>(r, exp += abs >> 10);
6402  return half(detail::binary, detail::rounded<half::round_style, false>((exp << 10) + (m & 0x3FF), r > m, r != 0));
6403 #endif
6404 }

◆ std::numeric_limits< half >

friend class std::numeric_limits< half >
friend

Definition at line 5350 of file half.hpp.

◆ tan

half tan ( half  arg)
friend

Tangent function. This function is exact to rounding for all rounding modes.

See also: Documentation for std::tan.

Parameters
argfunction argument
Returns
tangent value of arg
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN or infinity
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 6825 of file half.hpp.

6826 {
6827 #ifdef HALF_ARITHMETIC_TYPE
6828  return half(detail::binary, detail::float2half<half::round_style>(std::tan(detail::half2float<detail::internal_t>(arg.data_))));
6829 #else
6830  int abs = arg.data_ & 0x7FFF, exp = 13, k;
6831  if (!abs)
6832  return arg;
6833  if (abs >= 0x7C00)
6834  return half(detail::binary, (abs == 0x7C00) ? detail::invalid() : detail::signal(arg.data_));
6835  if (abs < 0x2700)
6836  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_, 0, 1));
6837  if (half::round_style != std::round_to_nearest)
6838  switch (abs)
6839  {
6840  case 0x658C:
6841  return half(detail::binary, detail::rounded<half::round_style, true>((arg.data_ & 0x8000) | 0x07E6, 1, 1));
6842  case 0x7330:
6843  return half(detail::binary, detail::rounded<half::round_style, true>((~arg.data_ & 0x8000) | 0x4B62, 1, 1));
6844  }
6845  std::pair<detail::uint32, detail::uint32> sc = detail::sincos(detail::angle_arg(abs, k), 30);
6846  if (k & 1)
6847  sc = std::make_pair(-sc.second, sc.first);
6848  detail::uint32 signy = detail::sign_mask(sc.first), signx = detail::sign_mask(sc.second);
6849  detail::uint32 my = (sc.first ^ signy) - signy, mx = (sc.second ^ signx) - signx;
6850  for (; my < 0x80000000; my <<= 1, --exp)
6851  ;
6852  for (; mx < 0x80000000; mx <<= 1, ++exp)
6853  ;
6854  return half(detail::binary, detail::tangent_post<half::round_style>(my, mx, exp, (signy ^ signx ^ arg.data_) & 0x8000));
6855 #endif
6856 }
half tan(half arg)
Definition: half.hpp:6825

◆ tanh

half tanh ( half  arg)
friend

Hyperbolic tangent. This function is exact to rounding for all rounding modes.

See also: Documentation for std::tanh.

Parameters
argfunction argument
Returns
hyperbolic tangent value of arg
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 7063 of file half.hpp.

7064 {
7065 #ifdef HALF_ARITHMETIC_TYPE
7066  return half(detail::binary, detail::float2half<half::round_style>(std::tanh(detail::half2float<detail::internal_t>(arg.data_))));
7067 #else
7068  int abs = arg.data_ & 0x7FFF, exp;
7069  if (!abs)
7070  return arg;
7071  if (abs >= 0x7C00)
7072  return half(detail::binary, (abs > 0x7C00) ? detail::signal(arg.data_) : (arg.data_ - 0x4000));
7073  if (abs >= 0x4500)
7074  return half(detail::binary, detail::rounded<half::round_style, true>((arg.data_ & 0x8000) | 0x3BFF, 1, 1));
7075  if (abs < 0x2700)
7076  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_ - 1, 1, 1));
7077  if (half::round_style != std::round_to_nearest && abs == 0x2D3F)
7078  return half(detail::binary, detail::rounded<half::round_style, true>(arg.data_ - 3, 0, 1));
7079  std::pair<detail::uint32, detail::uint32> mm = detail::hyperbolic_args(abs, exp, 27);
7080  detail::uint32 my = mm.first - mm.second - (half::round_style != std::round_to_nearest), mx = mm.first + mm.second, i = (~mx & 0xFFFFFFFF) >> 31;
7081  for (exp = 13; my < 0x80000000; my <<= 1, --exp)
7082  ;
7083  mx = (mx >> i) | 0x80000000;
7084  return half(detail::binary, detail::tangent_post<half::round_style>(my, mx, exp - i, arg.data_ & 0x8000));
7085 #endif
7086 }
half tanh(half arg)
Definition: half.hpp:7063

◆ tgamma

half tgamma ( half  arg)
friend

Gamma function. This function may be 1 ULP off the correctly rounded exact result for any rounding mode in <0.25% of inputs.

See also: Documentation for std::tgamma.

Parameters
argfunction argument
Returns
gamma function value of arg
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN, negative infinity or negative integer arguments
MU_HALF_FE_DIVBYZEROfor 0
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 7257 of file half.hpp.

7258 {
7259 #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
7260  return half(detail::binary, detail::float2half<half::round_style>(std::tgamma(detail::half2float<detail::internal_t>(arg.data_))));
7261 #else
7262  unsigned int abs = arg.data_ & 0x7FFF;
7263  if (!abs)
7264  return half(detail::binary, detail::pole(arg.data_));
7265  if (abs >= 0x7C00)
7266  return (arg.data_ == 0x7C00) ? arg : half(detail::binary, detail::signal(arg.data_));
7267  if (arg.data_ >= 0xE400 || (arg.data_ >= 0xBC00 && !(abs & ((1 << (25 - (abs >> 10))) - 1))))
7268  return half(detail::binary, detail::invalid());
7269  if (arg.data_ >= 0xCA80)
7270  return half(detail::binary, detail::underflow<half::round_style>((1 - ((abs >> (25 - (abs >> 10))) & 1)) << 15));
7271  if (arg.data_ <= 0x100 || (arg.data_ >= 0x4900 && arg.data_ < 0x8000))
7272  return half(detail::binary, detail::overflow<half::round_style>());
7273  if (arg.data_ == 0x3C00)
7274  return arg;
7275  return half(detail::binary, detail::gamma<half::round_style, false>(arg.data_));
7276 #endif
7277 }
half tgamma(half arg)
Definition: half.hpp:7257

◆ trunc

half trunc ( half  arg)
friend

Nearest integer not greater in magnitude than half value. See also: Documentation for std::trunc.

Parameters
arghalf to round
Returns
nearest integer not greater in magnitude than arg
Exceptions
MU_HALF_FE_INVALIDfor signaling NaN
MU_HALF_FE_INEXACTif value had to be rounded

Definition at line 7312 of file half.hpp.

7313 {
7314  return half(detail::binary, detail::integral<std::round_toward_zero, true, true>(arg.data_));
7315 }

The documentation for this class was generated from the following file: