std:: fdim, std:: fdimf, std:: fdiml

From cppreference.com
Common mathematical functions
Nearest integer floating point operations
(C++11)
(C++11)
(C++11) (C++11) (C++11)
Floating point manipulation functions
(C++11) (C++11)
(C++11)
(C++11)
Classification and comparison
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
Types
(C++11)
(C++11)
(C++11)
Macro constants
Defined in header <cmath>
(1)
float fdim ( float x, float y ) ;

double fdim ( double x, double y ) ;

long double fdim ( long double x, long double y ) ;
(until C++23)
constexpr /* floating-point-type */

fdim ( /* floating-point-type */ x,

/* floating-point-type */ y ) ;
(since C++23)
float fdimf ( float x, float y ) ;
(2) (since C++11)
(constexpr since C++23)
long double fdiml ( long double x, long double y ) ;
(3) (since C++11)
(constexpr since C++23)
Defined in header <cmath>
template < class Integer >
double fdim ( Integer x, Integer y ) ;
(A) (constexpr since C++23)
1-3) Returns the positive difference between x and y , that is, if x > y , returns x - y , otherwise (i.e. if x <= y ) returns + 0 . The library provides overloads of std::fdim for all cv-unqualified floating-point types as the type of the parameters. (since C++23)
A) Additional overloads are provided for all integer types, which are treated as double .
(since C++11)

Parameters

x, y - floating-point or integer values

Return value

If successful, returns the positive difference between x and y .

If a range error due to overflow occurs, +HUGE_VAL , +HUGE_VALF , or +HUGE_VALL is returned.

If a range error due to underflow occurs, the correct value (after rounding) is returned.

Error handling

Errors are reported as specified in math_errhandling .

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

  • If either argument is NaN, NaN is returned.

Notes

Equivalent to std:: fmax ( x - y, 0 ) , except for the NaN handling requirements.

The additional overloads are not required to be provided exactly as (A) . They only need to be sufficient to ensure that for their first argument num1 and second argument num2 :

  • If num1 or num2 has type long double , then std :: fdim ( num1, num2 ) has the same effect as std :: fdim ( static_cast < long double > ( num1 ) ,
    static_cast < long double > ( num2 ) )
    .
  • Otherwise, if num1 and/or num2 has type double or an integer type, then std :: fdim ( num1, num2 ) has the same effect as std :: fdim ( static_cast < double > ( num1 ) ,
    static_cast < double > ( num2 ) )
    .
  • Otherwise, if num1 or num2 has type float , then std :: fdim ( num1, num2 ) has the same effect as std :: fdim ( static_cast < float > ( num1 ) ,
    static_cast < float > ( num2 ) )
    .
(until C++23)

If num1 and num2 have arithmetic types, then std :: fdim ( num1, num2 ) has the same effect as std :: fdim ( static_cast < /* common-floating-point-type */ > ( num1 ) ,
static_cast < /* common-floating-point-type */ > ( num2 ) )
, where /* common-floating-point-type */ is the floating-point type with the greatest floating-point conversion rank and greatest floating-point conversion subrank between the types of num1 and num2 , arguments of integer type are considered to have the same floating-point conversion rank as double .

If no such floating-point type with the greatest rank and subrank exists, then overload resolution does not result in a usable candidate from the overloads provided.

(since C++23)

Example

#include <cerrno>
#include <cfenv>
#include <cmath>
#include <cstring>
#include <iostream>
 
#ifndef __GNUC__
#pragma STDC FENV_ACCESS ON
#endif
 
int main()
{
    std::cout << "fdim(4, 1) = " << std::fdim(4, 1) << '\n'
              << "fdim(1, 4) = " << std::fdim(1, 4) << '\n'
              << "fdim(4,-1) = " << std::fdim(4, -1) << '\n'
              << "fdim(1,-4) = " << std::fdim(1, -4) << '\n';
 
    // error handling 
    errno = 0;
    std::feclearexcept(FE_ALL_EXCEPT);
 
    std::cout << "fdim(1e308, -1e308) = " << std::fdim(1e308, -1e308) << '\n';
 
    if (errno == ERANGE)
        std::cout << "    errno == ERANGE: " << std::strerror(errno) << '\n';
    if (std::fetestexcept(FE_OVERFLOW))
        std::cout << "    FE_OVERFLOW raised\n";
}

Output:

fdim(4, 1) = 3
fdim(1, 4) = 0
fdim(4,-1) = 5
fdim(1,-4) = 5
fdim(1e308, -1e308) = inf
    errno == ERANGE: Numerical result out of range
    FE_OVERFLOW raised

See also

computes absolute value of an integral value ( |x| )
(function)
(C++11) (C++11) (C++11)
larger of two floating-point values
(function)