C++ 11 – <cfenv> Header
C++ 11 comes with new features and improvements and one of the main addition is the <cfenv> header that helps the programmers or developers with great control over the floating-point environment. It governs critical features of floating-point arithmetic like rounding modes and exceptions. <cfenv> gives programmers the tools they need to control and query the floating-point environment by offering a collection of functions and macros.
Syntax
#include <cfenv>
Now let’s understand some methods which are available in <cfenv> header file with their suitable examples like rounding mode change and handling Floating point Exceptions which are crucial features of the header <cfenv>.
cfenv Functions
1. fegetenv()
It is a function to retrieve the current floating-point environment.
Syntax
int fegetenv(fenv_t* envp);
Where env is the environment variable.
Return Value
- If successful, it returns zero.
- Returns non-zero value if an error occurs.
2. fesetenv()
It is a function to set the current floating-point environment.
Syntax
int fesetenv (const fenv_t* envp);
Return Value
- fesetenv() returns zero if successful, otherwise,
- It returns a nonzero value if an error occurs.
3. feholdexcept()
It is a function to save the current floating-point environment and clear all floating-point status flags.
Syntax
feholdexcept (fenv_t* envp);
Parameters
- envp is a pointer to an object of type fenv_t that will store the saved floating-point environment.
Return Value
- feholdexcept() returns zero if successful, otherwise,
- It returns a nonzero value if an error occurs.
4. feraiseexcept()
It is a function to raise a specified floating-point exception.
Syntax
feraiseexcept(int excepts);
Parameters
- excepts is the floating-point exception or exceptions to be raised.
Return Value
- feraiseexcept() returns zero if successful, otherwise,
- It returns a nonzero value if an error occurs.
Below are the floating point exceptions present in except:
- FE_INVALID: Invalid floating-point operation exception.
- FE_DIVBYZERO: Division by zero exception.
- FE_OVERFLOW: Overflow exception.
- FE_UNDERFLOW: Underflow exception.
- FE_INEXACT: Inexact result exception.
5. fetestexcept()
It is a function to test specified floating-point status flags.
Syntax
if (fetestexcept(FE_INVALID)) { // Handle invalid operation }
Now let’s understand these functions with the help of some examples.
Example 1: Changing the Rounding Mode
In this example, we will see how to set the rounding mode to run toward zero using fesetround() function.
C++
// C++ example to illustrate the fesetround() #include <cfenv> #include <iostream> using namespace std; int main() { // Set the rounding mode to round towards zero fesetround(FE_TOWARDZERO); // Perform some floating-point operations double result = 10.5 / 3.0; cout << "Result (round toward zero): " << result << endl; return 0; } |
Result (round toward zero): 3.5
We can also save the current floating-point environment by using the std::fegetenv() from the <cfenv> header and below will be an example.
A variable current_environment is declared to store the current environment and std::fegetenv() will be used to retrieve the current environment.
C++
// C++ program to illustrate the fesetround #include <cfenv> #include <iostream> using namespace std; int main() { // Save the current floating-point environment fenv_t current_environment; fegetenv(¤t_environment); // Set the rounding mode to round towards zero fesetround(FE_TOWARDZERO); // Perform some floating-point operations double result = 10.5 / 3.0; cout << "Result (round toward zero): " << result << endl; return 0; } |
Result (round toward zero): 3.5
Example 2: Handling Floating-Point Exceptions
In this example, we will be focusing on handling floating point exceptions. A variable exception_flag of type std::fexcept_t is declared to store the floating point exception flag and then a division is performed which should trigger division by zero exception. If the FE_DIVBYZERO flag is set in the Flags_encountered, it indicates that a division by zero exception occurred and will store the result and print it.
C++
// C++ program to illustrate the fesetexceptflag() #include <cfenv> #include <iostream> using namespace std; int main() { fexcept_t exception_flags; fesetexceptflag(&exception_flags, FE_ALL_EXCEPT); // Division by zero double result = 1.0 / 0.0; cout << "Result: " << result << endl; int Flags_encountered = fetestexcept(FE_ALL_EXCEPT); if (Flags_encountered & FE_DIVBYZERO) { cout << "Division by zero exception occurred!" << endl; } if (Flags_encountered & FE_OVERFLOW) { cout << "Overflow exception occurred!" << endl; } return 0; } |
Result: inf Division by zero exception occurred!