YouTip LogoYouTip

C Standard Library Fenv H

### C Standard Library `` `` is a header file in the C standard library used to control the floating-point environment. `` was introduced in the C99 standard and provides functions for controlling and querying floating-point exceptions, rounding modes, and other floating-point states. * * * The main purposes of `` are: * Detect and handle floating-point exceptions (such as division by zero, overflow, etc.). * Control the rounding mode of floating-point operations (such as rounding toward zero, rounding to nearest, etc.). * Query and modify floating-point status flags. * * * ### 1、**Floating-Point Exceptions** Floating-point exceptions are special conditions that occur during floating-point operations, such as: * **FE_DIVBYZERO**: Division by zero. * **FE_INEXACT**: Inexact result. * **FE_INVALID**: Invalid operation (such as square root of a negative number). * **FE_OVERFLOW**: Overflow. * **FE_UNDERFLOW**: Underflow. These exceptions are represented by floating-point status flags and can be detected and handled through functions in ``. * * * ### 2、**Rounding Modes** Rounding modes control how floating-point operation results are rounded. `` defines the following rounding modes: * **FE_TONEAREST**: Round to the nearest value (default mode). * **FE_DOWNWARD**: Round toward negative infinity. * **FE_UPWARD**: Round toward positive infinity. * **FE_TOWARDZERO**: Round toward zero. * * * ### 3、**Main Functions and Macros** `` provides a set of functions and macros for manipulating the floating-point environment and handling floating-point exceptions. #### Floating-Point Exception Handling | Function/Macro | Description | | --- | --- | | `feclearexcept(int excepts)` | Clear the specified floating-point exception flags | | `feraiseexcept(int excepts)` | Raise the specified floating-point exception | | `fetestexcept(int excepts)` | Test whether the specified floating-point exception occurred | | `fegetexceptflag(fexcept_t *flagp, int excepts)` | Get the floating-point exception flag status | | `fesetexceptflag(const fexcept_t *flagp, int excepts)` | Set the floating-point exception flag status | #### Rounding Mode Control | Function/Macro | Description | | --- | --- | | `fegetround(void)` | Get the current rounding mode | | `fesetround(int round)` | Set the current rounding mode | #### Floating-Point Environment Control | Function/Macro | Description | | --- | --- | | `fegetenv(fenv_t *envp)` | Save the current floating-point environment | | `fesetenv(const fenv_t *envp)` | Restore the floating-point environment | | `feholdexcept(fenv_t *envp)` | Save the current floating-point environment and clear exception flags | | `feupdateenv(const fenv_t *envp)` | Restore the floating-point environment and raise exceptions | * * * ### 4、**Examples** The following is an example using `` that demonstrates how to detect floating-point exceptions and control the rounding mode: ## Example #include #include #include int main(){ // Enable floating-point exception detection feclearexcept(FE_ALL_EXCEPT); // Raise division by zero exception double x =1.0, y =0.0; double z = x / y; // Check if division by zero exception occurred if(fetestexcept(FE_DIVBYZERO)){ printf("Divide by zero exception occurred.n"); } // Set rounding mode to round toward zero fesetround(FE_TOWARDZERO); // Test rounding mode double a =1.5; double b = rint(a);// Round to integer printf("Rounding 1.5 toward zero: %.1fn", b); return 0; } The output is: Divide by zero exception occurred.Rounding 1.5 toward zero: 1.0 **Detecting Floating-Point Exceptions** ## Example #include #include #include #pragma STDC FENV_ACCESS ON void check_exceptions(){ // Clear all exception flags feclearexcept(FE_ALL_EXCEPT); // Perform operations that may raise exceptions double x =0.0; double y =1.0/ x;// Division by zero // Check for specific exception if(fetestexcept(FE_DIVBYZERO)){ printf("Division by zero occurred!n"); } // Check for any exception if(fetestexcept(FE_ALL_EXCEPT)){ printf("At least one floating-point exception occurredn"); } } int main(){ check_exceptions(); return 0; } **Controlling Rounding Direction** ## Example #include #include #pragma STDC FENV_ACCESS ON void test_rounding(double num){ int modes[]={FE_TONEAREST, FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO}; const char*names[]={"Nearest","Up","Down","Toward zero"}; for(int i =0; i %.0fn", names, num, rint(num)); } } } int main(){ test_rounding(2.5);// Test 2.5 with different rounding modes test_rounding(-2.5);// Test -2.5 with different rounding modes return 0; } **Saving and Restoring Floating-Point Environment** ## Example #include #include #include #pragma STDC FENV_ACCESS ON void sensitive_calculation(){ fenv_t env; // Save current environment fegetenv(&env); // Set strict environment: catch all exceptions feclearexcept(FE_ALL_EXCEPT); // Perform critical calculation double result =sqrt(-1.0);// Invalid operation if(fetestexcept(FE_INVALID)){ printf("Invalid operation detected in sensitive calculationn"); } // Restore original environment fesetenv(&env); } int main(){ sensitive_calculation(); return 0; } **Temporarily Masking Exceptions** ## Example #include #include #include #pragma STDC FENV_ACCESS ON void temp_disable_exceptions(){ fenv_t env; // Save environment and temporarily mask all exceptions feholdexcept(&env); // Perform operations that may produce exceptions double x =0.0; double y =1.0/ x;// Will not raise exception printf("Division by zero was performed but not reportedn"); // Restore environment and handle previously raised exceptions feupdateenv(&env); // Now we can check for exceptions if(fetestexcept(FE_DIVBYZERO)){ printf("Division by zero was detected after restoring environmentn"); } } int main(){ temp_disable_exceptions(); return 0; } **Precise Calculation Example** ## Example #include #include #include #pragma STDC FENV_ACCESS ON double precise_sum(double a,double b){ int original_round = fegetround(); fenv_t env; // Save environment and set highest precision mode fegetenv(&env); fesetround(FE_TONEAREST); feclearexcept(FE_ALL_EXCEPT); double result = a + b; // Check if calculation was exact if(fetestexcept(FE_INEXACT)){ printf("Warning: Sum was not exact, possible precision lossn"); } // Restore original environment fesetround(original_round); fesetenv(&env); return result; } int main(){ double a =1.0/3.0; double b =2.0/3.0; printf("Sum: %.17gn", precise_sum(a, b)); return 0; } **Exception Handling Wrapper** ## Example #include #include #include #pragma STDC FENV_ACCESS ON typedef double(*math_func)(double); double safe_math(math_func f,double x,int*error){ fenv_t env; *error =0
← Pandas Dataframe Api ReferenceC Standard Library Complex H β†’