MU Library
half_float Namespace Reference

Namespaces

 detail
 

Classes

class  half
 

Functions

Comparison operators

HALF_CONSTEXPR_NOERR bool operator== (half x, half y)
 
HALF_CONSTEXPR_NOERR bool operator!= (half x, half y)
 
HALF_CONSTEXPR_NOERR bool operator< (half x, half y)
 
HALF_CONSTEXPR_NOERR bool operator> (half x, half y)
 
HALF_CONSTEXPR_NOERR bool operator<= (half x, half y)
 
HALF_CONSTEXPR_NOERR bool operator>= (half x, half y)
 
Arithmetic operators

HALF_CONSTEXPR half operator+ (half arg)
 
HALF_CONSTEXPR half operator- (half arg)
 
half operator+ (half x, half y)
 
half operator- (half x, half y)
 
half operator* (half x, half y)
 
half operator/ (half x, half y)
 
Basic mathematical operations

HALF_CONSTEXPR half fabs (half arg)
 
HALF_CONSTEXPR half abs (half arg)
 
half fmod (half x, half y)
 
half remainder (half x, half y)
 
half remquo (half x, half y, int *quo)
 
half fma (half x, half y, half z)
 
HALF_CONSTEXPR_NOERR half fmax (half x, half y)
 
HALF_CONSTEXPR_NOERR half fmin (half x, half y)
 
half fdim (half x, half y)
 
half nanh (const char *arg)
 
Exponential functions

half exp (half arg)
 
half exp2 (half arg)
 
half expm1 (half arg)
 
half log (half arg)
 
half log10 (half arg)
 
half log2 (half arg)
 
half log1p (half arg)
 
Power functions

half sqrt (half arg)
 
half rsqrt (half arg)
 
half cbrt (half arg)
 
half hypot (half x, half y)
 
half hypot (half x, half y, half z)
 
half pow (half x, half y)
 
Trigonometric functions

void sincos (half arg, half *sin, half *cos)
 
half sin (half arg)
 
half cos (half arg)
 
half tan (half arg)
 
half asin (half arg)
 
half acos (half arg)
 
half atan (half arg)
 
half atan2 (half y, half x)
 
Hyperbolic functions

half sinh (half arg)
 
half cosh (half arg)
 
half tanh (half arg)
 
half asinh (half arg)
 
half acosh (half arg)
 
half atanh (half arg)
 
Error and gamma functions

half erf (half arg)
 
half erfc (half arg)
 
half lgamma (half arg)
 
half tgamma (half arg)
 
Rounding

half ceil (half arg)
 
half floor (half arg)
 
half trunc (half arg)
 
half round (half arg)
 
long lround (half arg)
 
half rint (half arg)
 
long lrint (half arg)
 
half nearbyint (half arg)
 
Floating point manipulation

half frexp (half arg, int *exp)
 
half scalbln (half arg, long exp)
 
half scalbn (half arg, int exp)
 
half ldexp (half arg, int exp)
 
half modf (half arg, half *iptr)
 
int ilogb (half arg)
 
half logb (half arg)
 
half nextafter (half from, half to)
 
half nexttoward (half from, long double to)
 
HALF_CONSTEXPR half copysign (half x, half y)
 
Floating point classification

HALF_CONSTEXPR int fpclassify (half arg)
 
HALF_CONSTEXPR bool isfinite (half arg)
 
HALF_CONSTEXPR bool isinf (half arg)
 
HALF_CONSTEXPR bool isnan (half arg)
 
HALF_CONSTEXPR bool isnormal (half arg)
 
HALF_CONSTEXPR bool signbit (half arg)
 
Comparison

HALF_CONSTEXPR bool isgreater (half x, half y)
 
HALF_CONSTEXPR bool isgreaterequal (half x, half y)
 
HALF_CONSTEXPR bool isless (half x, half y)
 
HALF_CONSTEXPR bool islessequal (half x, half y)
 
HALF_CONSTEXPR bool islessgreater (half x, half y)
 
HALF_CONSTEXPR bool isunordered (half x, half y)
 
Casting

template<typename T , typename U >
half_cast (U arg)
 
template<typename T , std::float_round_style R, typename U >
half_cast (U arg)
 
Error handling

int feclearexcept (int excepts)
 
int fetestexcept (int excepts)
 
int feraiseexcept (int excepts)
 
int fegetexceptflag (int *flagp, int excepts)
 
int fesetexceptflag (const int *flagp, int excepts)
 
void fethrowexcept ([[maybe_unused]] int excepts, [[maybe_unused]] const char *msg="")
 

Detailed Description

Main namespace for half-precision functionality. This namespace contains all the functionality provided by the library.

Function Documentation

◆ abs()

HALF_CONSTEXPR half half_float::abs ( half  arg)
inline

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

Parameters
argoperand
Returns
absolute value of arg

Definition at line 5905 of file half.hpp.

5906 {
5907  return fabs(arg);
5908 }
HALF_CONSTEXPR half fabs(half arg)
Definition: half.hpp:5896

◆ acos()

half half_float::acos ( half  arg)
inline

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 }
HALF_CONSTEXPR_CONST binary_t binary
Tag for binary construction.
Definition: half.hpp:635
std::pair< uint32, uint32 > atan2_args(unsigned int abs)
Definition: half.hpp:4640
HALF_CONSTEXPR_NOERR unsigned int signal(unsigned int x, unsigned int y, unsigned int z)
Definition: half.hpp:824
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 atan2(half y, half x)
Definition: half.hpp:6950
half acos(half arg)
Definition: half.hpp:6895

◆ acosh()

half half_float::acosh ( half  arg)
inline

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 half_float::asin ( half  arg)
inline

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 half_float::asinh ( half  arg)
inline

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 half_float::atan ( half  arg)
inline

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 }
half atan(half arg)
Definition: half.hpp:6921
half exp(half arg)
Definition: half.hpp:6111

◆ atan2()

half half_float::atan2 ( half  y,
half  x 
)
inline

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

◆ atanh()

half half_float::atanh ( half  arg)
inline

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 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
half log2(half arg)
Definition: half.hpp:6292

◆ cbrt()

half half_float::cbrt ( half  arg)
inline

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 multiply64(uint32 x, uint32 y)
Definition: half.hpp:4259
uint32 sign_mask(uint32 arg)
Definition: half.hpp:693
half exp2(half arg)
Definition: half.hpp:6146
half cbrt(half arg)
Definition: half.hpp:6454

◆ ceil()

half half_float::ceil ( half  arg)
inline

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 half_float::copysign ( half  x,
half  y 
)
inline

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 half_float::cos ( half  arg)
inline

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 }
uint32 angle_arg(unsigned int abs, int &k)
Definition: half.hpp:4617
half cos(half arg)
Definition: half.hpp:6797
void sincos(half arg, half *sin, half *cos)
Definition: half.hpp:6690

◆ cosh()

half half_float::cosh ( half  arg)
inline

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

◆ erf()

half half_float::erf ( half  arg)
inline

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 half_float::erfc ( half  arg)
inline

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 half_float::exp ( half  arg)
inline

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 }

◆ exp2()

half half_float::exp2 ( half  arg)
inline

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 }

◆ expm1()

half half_float::expm1 ( half  arg)
inline

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 half_float::fabs ( half  arg)
inline

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 half_float::fdim ( half  x,
half  y 
)
inline

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 }
HALF_CONSTEXPR bool isnan(half arg)
Definition: half.hpp:7654

◆ feclearexcept()

int half_float::feclearexcept ( int  excepts)
inline

Clear exception flags. This function works even if automatic exception flag handling is disabled, but in that case manual flag management is the only way to raise flags.

See also: Documentation for std::feclearexcept.

Parameters
exceptsOR of exceptions to clear
Return values
0all selected flags cleared successfully

Definition at line 7807 of file half.hpp.

7808 {
7809  detail::errflags() &= ~excepts;
7810  return 0;
7811 }
int & errflags()
Definition: half.hpp:722

◆ fegetexceptflag()

int half_float::fegetexceptflag ( int *  flagp,
int  excepts 
)
inline

Save exception flags. This function works even if automatic exception flag handling is disabled, but in that case manual flag management is the only way to raise flags.

See also: Documentation for std::fegetexceptflag.

Parameters
flagpadress to store flag state at
exceptsOR of flags to save
Return values
0for success

Definition at line 7849 of file half.hpp.

7850 {
7851  *flagp = detail::errflags() & excepts;
7852  return 0;
7853 }

◆ feraiseexcept()

int half_float::feraiseexcept ( int  excepts)
inline

Raise exception flags. This raises the specified floating point exceptions and also invokes any additional automatic exception handling as configured with the HALF_ERRHANDLIG_... preprocessor symbols. This function works even if automatic exception flag handling is disabled, but in that case manual flag management is the only way to raise flags.

See also: Documentation for std::feraiseexcept.

Parameters
exceptsOR of exceptions to raise
Return values
0all selected exceptions raised successfully

Definition at line 7834 of file half.hpp.

7835 {
7836  detail::errflags() |= excepts;
7837  detail::raise(excepts);
7838  return 0;
7839 }
void raise(int HALF_UNUSED_NOERR(flags), bool HALF_UNUSED_NOERR(cond)=true)
Definition: half.hpp:731

◆ fesetexceptflag()

int half_float::fesetexceptflag ( const int *  flagp,
int  excepts 
)
inline

Restore exception flags. This only copies the specified exception state (including unset flags) without incurring any additional exception handling. This function works even if automatic exception flag handling is disabled, but in that case manual flag management is the only way to raise flags.

See also: Documentation for std::fesetexceptflag.

Parameters
flagpadress to take flag state from
exceptsOR of flags to restore
Return values
0for success

Definition at line 7864 of file half.hpp.

7865 {
7866  detail::errflags() = (detail::errflags() | (*flagp & excepts)) & (*flagp | ~excepts);
7867  return 0;
7868 }

◆ fetestexcept()

int half_float::fetestexcept ( int  excepts)
inline

Test exception flags. This function works even if automatic exception flag handling is disabled, but in that case manual flag management is the only way to raise flags.

See also: Documentation for std::fetestexcept.

Parameters
exceptsOR of exceptions to test
Returns
OR of selected exceptions if raised

Definition at line 7820 of file half.hpp.

7821 {
7822  return detail::errflags() & excepts;
7823 }

◆ fethrowexcept()

void half_float::fethrowexcept ( [[maybe_unused] ] int  excepts,
[[maybe_unused] ] const char *  msg = "" 
)
inline

Throw C++ exceptions based on set exception flags. This function manually throws a corresponding C++ exception if one of the specified flags is set, no matter if automatic throwing (via HALF_ERRHANDLING_THROW_...) is enabled or not. This function works even if automatic exception flag handling is disabled, but in that case manual flag management is the only way to raise flags.

Parameters
exceptsOR of exceptions to test
msgerror message to use for exception description
Exceptions
std::domain_errorif MU_HALF_FE_INVALID or MU_HALF_FE_DIVBYZERO is selected and set
std::overflow_errorif MU_HALF_FE_OVERFLOW is selected and set
std::underflow_errorif MU_HALF_FE_UNDERFLOW is selected and set
std::range_errorif MU_HALF_FE_INEXACT is selected and set

Definition at line 7881 of file half.hpp.

7882 {
7883  // ERASED
7884  // excepts &= detail::errflags();
7885  // if(excepts & (MU_HALF_FE_INVALID|MU_HALF_FE_DIVBYZERO))
7886  // throw std::domain_error(msg);
7887  // if(excepts & MU_HALF_FE_OVERFLOW)
7888  // throw std::overflow_error(msg);
7889  // if(excepts & MU_HALF_FE_UNDERFLOW)
7890  // throw std::underflow_error(msg);
7891  // if(excepts & MU_HALF_FE_INEXACT)
7892  // throw std::range_error(msg);
7893 }

◆ floor()

half half_float::floor ( half  arg)
inline

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 half_float::fma ( half  x,
half  y,
half  z 
)
inline

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 half_float::fmax ( half  x,
half  y 
)
inline

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 half_float::fmin ( half  x,
half  y 
)
inline

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 half_float::fmod ( half  x,
half  y 
)
inline

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 half_float::fpclassify ( half  arg)
inline

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 half_float::frexp ( half  arg,
int *  exp 
)
inline

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 }

◆ half_cast() [1/2]

template<typename T , typename U >
T half_float::half_cast ( arg)

Cast to or from half-precision floating-point number. This casts between half and any built-in arithmetic type. The values are converted directly using the default rounding mode, without any roundtrip over float that a static_cast would otherwise do.

Using this cast with neither of the two types being a half or with any of the two types not being a built-in arithmetic type (apart from half, of course) results in a compiler error and casting between halfs returns the argument unmodified.

Template Parameters
Tdestination type (half or built-in arithmetic type)
Usource type (half or built-in arithmetic type)
Parameters
argvalue to cast
Returns
arg converted to destination type
Exceptions
MU_HALF_FE_INVALIDif T is integer type and result is not representable as T
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 7769 of file half.hpp.

7770 {
7771  return detail::half_caster<T, U>::cast(arg);
7772 }

◆ half_cast() [2/2]

template<typename T , std::float_round_style R, typename U >
T half_float::half_cast ( arg)

Cast to or from half-precision floating-point number. This casts between half and any built-in arithmetic type. The values are converted directly using the specified rounding mode, without any roundtrip over float that a static_cast would otherwise do.

Using this cast with neither of the two types being a half or with any of the two types not being a built-in arithmetic type (apart from half, of course) results in a compiler error and casting between halfs returns the argument unmodified.

Template Parameters
Tdestination type (half or built-in arithmetic type)
Rrounding mode to use.
Usource type (half or built-in arithmetic type)
Parameters
argvalue to cast
Returns
arg converted to destination type
Exceptions
MU_HALF_FE_INVALIDif T is integer type and result is not representable as T
MU_HALF_FE_OVERFLOW,...UNDERFLOW,...INEXACTaccording to rounding

Definition at line 7789 of file half.hpp.

7790 {
7791  return detail::half_caster<T, U, R>::cast(arg);
7792 }

◆ hypot() [1/2]

half half_float::hypot ( half  x,
half  y 
)
inline

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)
6521  return half(detail::binary, detail::check_underflow(absx));
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 half_float::hypot ( half  x,
half  y,
half  z 
)
inline

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 }

◆ ilogb()

int half_float::ilogb ( half  arg)
inline

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

◆ isfinite()

HALF_CONSTEXPR bool half_float::isfinite ( half  arg)
inline

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 half_float::isgreater ( half  x,
half  y 
)
inline

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 half_float::isgreaterequal ( half  x,
half  y 
)
inline

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 half_float::isinf ( half  arg)
inline

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 half_float::isless ( half  x,
half  y 
)
inline

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 half_float::islessequal ( half  x,
half  y 
)
inline

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 half_float::islessgreater ( half  x,
half  y 
)
inline

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 half_float::isnan ( half  arg)
inline

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 half_float::isnormal ( half  arg)
inline

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 }

◆ isunordered()

HALF_CONSTEXPR bool half_float::isunordered ( half  x,
half  y 
)
inline

Quiet check if unordered. See also: Documentation for std::isunordered.

Parameters
xfirst operand
ysecond operand
Return values
trueif unordered (one or two NaN operands)
falseelse

Definition at line 7745 of file half.hpp.

7746 {
7747  return isnan(x) || isnan(y);
7748 }

◆ ldexp()

half half_float::ldexp ( half  arg,
int  exp 
)
inline

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

See also: Documentation for std::ldexp.

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 7465 of file half.hpp.

7466 {
7467  return scalbln(arg, exp);
7468 }
half scalbln(half arg, long exp)
Definition: half.hpp:7424

◆ lgamma()

half half_float::lgamma ( half  arg)
inline

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 half_float::log ( half  arg)
inline

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 half_float::log10 ( half  arg)
inline

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 half_float::log1p ( half  arg)
inline

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 half_float::log2 ( half  arg)
inline

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 }

◆ logb()

half half_float::logb ( half  arg)
inline

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 half_float::lrint ( half  arg)
inline

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 half_float::lround ( half  arg)
inline

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 half_float::modf ( half  arg,
half iptr 
)
inline

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 half_float::nanh ( const char *  arg)
inline

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 half_float::nearbyint ( half  arg)
inline

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 half_float::nextafter ( half  from,
half  to 
)
inline

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 }
#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 half_float::nexttoward ( half  from,
long double  to 
)
inline

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 half_float::operator!= ( half  x,
half  y 
)
inline

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 half_float::operator* ( half  x,
half  y 
)
inline

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+() [1/2]

HALF_CONSTEXPR half half_float::operator+ ( half  arg)
inline

Identity.

Parameters
argoperand
Returns
unchanged operand

Definition at line 5691 of file half.hpp.

5692 {
5693  return arg;
5694 }

◆ operator+() [2/2]

half half_float::operator+ ( half  x,
half  y 
)
inline

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 half_float::operator- ( half  arg)
inline

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 half_float::operator- ( half  x,
half  y 
)
inline

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 half_float::operator/ ( half  x,
half  y 
)
inline

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 half_float::operator< ( half  x,
half  y 
)
inline

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 half_float::operator<= ( half  x,
half  y 
)
inline

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 half_float::operator== ( half  x,
half  y 
)
inline

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 half_float::operator> ( half  x,
half  y 
)
inline

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 half_float::operator>= ( half  x,
half  y 
)
inline

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 half_float::pow ( half  x,
half  y 
)
inline

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 }
half pow(half x, half y)
Definition: half.hpp:6620

◆ remainder()

half half_float::remainder ( half  x,
half  y 
)
inline

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 half_float::remquo ( half  x,
half  y,
int *  quo 
)
inline

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 half_float::rint ( half  arg)
inline

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 half_float::round ( half  arg)
inline

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 half_float::rsqrt ( half  arg)
inline

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 }

◆ scalbln()

half half_float::scalbln ( half  arg,
long  exp 
)
inline

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 }

◆ scalbn()

half half_float::scalbn ( half  arg,
int  exp 
)
inline

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

See also: Documentation for std::scalbn.

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 7451 of file half.hpp.

7452 {
7453  return scalbln(arg, exp);
7454 }

◆ signbit()

HALF_CONSTEXPR bool half_float::signbit ( half  arg)
inline

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 half_float::sin ( half  arg)
inline

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 half_float::sincos ( half  arg,
half sin,
half cos 
)
inline

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 }

◆ sinh()

half half_float::sinh ( half  arg)
inline

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 half_float::sqrt ( half  arg)
inline

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 }

◆ tan()

half half_float::tan ( half  arg)
inline

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 half_float::tanh ( half  arg)
inline

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 half_float::tgamma ( half  arg)
inline

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 half_float::trunc ( half  arg)
inline

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 }