std::erfc,s...f,std::erfcl(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

🌸 std::erfc, std::erfcf, std::erfcl β€” C++ Standard Library πŸ’…

okay bestie, buckle up, because we're about to get statistically iconic. this is the manual page for std::erfc, std::erfcf and std::erfcl, straight out of the C++ Standard Library (the cppreference.com girlies, edition 2024.06.10), and she is lowkey doing the most important math in all of probability. ✨


πŸ’– NAME

std::erfc, std::erfcf, std::erfcl β€” yes she's just naming herself three times, it's giving main character energy, we love a self-referential moment. 🫢


πŸŽ€ Synopsis

Defined in header <cmath>:

float       erfc ( float num );

double      erfc ( double num );                            (until C++23)

long double erfc ( long double num );
/* floating-point-type */                                   (since C++23)
                erfc ( /* floating-point-type */ num );
(constexpr since C++26)

float       erfcf( float num );                     (1) (2) (since C++11)
                                                    (constexpr since C++26)

long double erfcl( long double num );                   (3) (since C++11)
                                                    (constexpr since C++26)

Additional overloads, since C++11, also in header <cmath>:

template< class Integer >                               (A)
(constexpr since C++26)
double      erfc ( Integer num );

so like, what do those actually do? πŸ¦‹

  1. 1-3): computes the complementary error function of num, which is literally 1.0 - std::erf(num), but β€” and this is the slay β€” without loss of precision for large num. she said "I will not be doing catastrophic cancellation today, thank you". πŸ’€
  2. the library provides overloads of std::erfc for all cv-unqualified floating-point types as the type of the parameter. (since C++23) β€” every float type gets her moment, no cap.
  3. A): additional overloads are provided for all integer types, which are treated as double. (since C++11) β€” integers are welcome here, they just get a little promotion first, iykyk.

🌈 Parameters

  • num β€” a floating-point or integer value. that's it. that's the whole parameter list. she's low maintenance. πŸ™ˆ

⭐ Return value

If no errors occur, you get the value of the complementary error function of num, bestie, which is:

\(\frac{2}{\sqrt{\pi} }\int_{num}^{\infty}{e^{-{t^2} }\mathsf{d}t}\)

β€” which, rendered the way the page renders it, is:

  2
 √
 Ο€

 ∫∞
 nume^-t2
 dt

or, in the other flavour, \({\small 1-\operatorname{erf}(num)}\) β†’ 1-erf(num). same girl, different outfit. πŸ’œ

If a range error occurs due to underflow, the correct result (after rounding) is returned. so even when she's running on fumes she still gives you the right answer. queen behaviour. πŸ‘‘


πŸ”₯ Error handling

Errors are reported as specified in math_errhandling.

If the implementation supports IEEE floating-point arithmetic (IEC 60559), then:

  • if the argument is +∞, +0 is returned. 🫧
  • if the argument is -∞, 2 is returned.
  • if the argument is NaN, NaN is returned. (as she should, honestly)

πŸ¦‹ Notes

For the IEEE-compatible type double, underflow is guaranteed if num > 26.55. not "maybe", not "sometimes", guaranteed. write that number down bestie. πŸ”₯

The additional overloads are not required to be provided exactly as (A). They only need to be sufficient to ensure that for their argument num of integer type, std::erfc(num) has the same effect as std::erfc(static_cast<double>(num)). so the vibe is "same result, implementation's choice of how", periodt. πŸ’…


✨ Example

// Run this code

#include <cmath>
#include <iomanip>
#include <iostream>

double normalCDF(double x) // Phi(-∞, x) aka N(x)
{
    return std::erfc(-x / std::sqrt(2)) / 2;
}

int main()
{
    std::cout << "normal cumulative distribution function:\n"
              << std::fixed << std::setprecision(2);
    for (double n = 0; n < 1; n += 0.1)
        std::cout << "normalCDF(" << n << ") = " << 100 * normalCDF(n)
       << "%\n";

    std::cout << "special values:\n"
              << "erfc(-Inf) = " << std::erfc(-INFINITY) << '\n'
              << "erfc(Inf) = " << std::erfc(INFINITY) << '\n';
}

🌸 Output

normal cumulative distribution function:
normalCDF(0.00) = 50.00%
normalCDF(0.10) = 53.98%
normalCDF(0.20) = 57.93%
normalCDF(0.30) = 61.79%
normalCDF(0.40) = 65.54%
normalCDF(0.50) = 69.15%
normalCDF(0.60) = 72.57%
normalCDF(0.70) = 75.80%
normalCDF(0.80) = 78.81%
normalCDF(0.90) = 81.59%
normalCDF(1.00) = 84.13%
special values:
erfc(-Inf) = 2.00
erfc(Inf) = 0.00

like, she literally computed a normal CDF from scratch in a for-loop. ate. πŸ’…βœ¨


πŸ‘‘ See also

  • erf
  • erff
  • erfl β€” error function (C++11) (function) (C++11) (C++11)
  • C documentation for erfc

  • Weisstein, Eric W. "Erfc." From MathWorld β€” A Wolfram Web Resource.

πŸ’€ real talk bestie: the num > 26.55 underflow thing is a hard guarantee for IEEE double, and the error reporting follows math_errhandling β€” that's not me being dramatic, that's the spec. 🫢

and that's the whole page!! source: cppreference.com, dated 2024.06.10, page std::erfc,s...f,std::erfcl(3). go forth and compute complementary error functions responsibly, my love. πŸŽ€πŸ’–πŸŒ·

πŸ“¦ where this page comes from