C standard library - Detailed explanation of <math.h> and <setjmp.h>

Table of contents

Introduction

Kuhong

Library Functions

Example

Introduction

library variables

Library Functions

Example


<math.h>

Introduction

<math.h> is a header file in the C standard library, which mainly provides function and macro definitions related to mathematical operations. It allows you to perform a variety of common mathematical calculations in C programs, such as trigonometric functions, logarithms, exponentials, power operations, etc.

Kuhong

The following is the only macro defined in this library:

HUGE_VAL is a macro defined in the <math.h> header file, used to represent a specific large value. When the result of a mathematical function cannot be represented as a floating point number, HUGE_VAL can be used to represent the out-of-range result.

Specifically, if the function's result is too large to be represented, the function sets errno to ERANGE, indicating a range error, and returns HUGE_VAL or -HUGE_VAL. This allows you to determine whether a function returned a value outside the representable range.

On the other hand, if the magnitude of the function's result is too small, it may return a zero value. In this case, errno may or may not be set to ERANGE. Therefore, when using mathematical functions and handling their return values, care needs to be taken to check whether the value of errno indicates an error.

In summary, the HUGE_VAL macro is very useful for handling values ​​outside the representable range and can help with error handling and bounds checking.

Library Functions

The functions defined in the header file math.h are listed below:

  1. double acos(double x): Returns the inverse cosine of x in radians.
  2. double asin(double x): Returns the arcsine of x in radians.
  3. double atan(double x): Returns the arc tangent of x in radians.
  4. double atan2(double y, double x): Returns the arctangent of y/x in radians. The sign of the y and x values ​​determines the correct quadrant.
  5. double cos(double x): Returns the cosine of the angle x in radians.
  6. double cosh(double x): Returns the hyperbolic cosine of x.
  7. double sin(double x): Returns the sine of the angle x in radians.
  8. double sinh(double x): Returns the hyperbolic sine of x.
  9. double tanh(double x): Returns the hyperbolic tangent of x.
  10. double exp(double x): Returns the value of e raised to the power of x.
  11. double frexp(double x, int *exponent): Decompose the floating point number x into mantissa and exponent. The return value is the mantissa and the exponent is stored in exponent. The resulting value is x = mantissa * 2 ^ exponent.
  12. double ldexp(double x, int exponent): Returns x multiplied by 2 raised to the exponent power.
  13. double log(double x): Returns the natural logarithm of x (logarithm in base e).
  14. double log10(double x): Returns the common logarithm (base 10 logarithm) of x.
  15. double modf(double x, double *integer): The return value is the decimal part (the part after the decimal point), and sets integer to the integer part.
  16. double pow(double x, double y): Returns x raised to the y power.
  17. double sqrt(double x): Returns the square root of x.
  18. double ceil(double x): Returns the smallest integer value greater than or equal to x.
  19. double fabs(double x): Returns the absolute value of x.
  20. double floor(double x): Returns the largest integer value less than or equal to x.
  21. double fmod(double x, double y): Returns the remainder of x divided by y.

Example

Here is a simple code example that shows how to use some functions in the <math.h> header file to perform mathematical calculations:

#include <stdio.h>
#include <math.h>  // 引入 math.h 头文件

int main() {
    double x = 1.5;
    double y = 2.7;

    // 计算 x 的双曲正弦值和反正切值
    double sinh_x = sinh(x);
    double atan_x = atan(x);

    // 计算 x 的立方根和以 2 为底的对数
    double cbrt_x = cbrt(x);
    double log2_x = log2(x);

    // 计算 y 的向下取整值和 x 与 y 的余数
    double floor_y = floor(y);
    double fmod_xy = fmod(x, y);

    // 打印计算结果
    printf("sinh(%.2f) = %.2f\n", x, sinh_x);
    printf("atan(%.2f) = %.2f\n", x, atan_x);
    printf("cbrt(%.2f) = %.2f\n", x, cbrt_x);
    printf("log2(%.2f) = %.2f\n", x, log2_x);
    printf("floor(%.2f) = %.2f\n", y, floor_y);
    printf("%.2f %% %.2f = %.2f\n", x, y, fmod_xy);

    return 0;
}

It should be noted that these functions need to be used with special care, because they may produce some abnormal conditions (such as exceeding the computer numerical range, etc.).

Let's compile and run the above program, which will produce the following results:

sinh(1.50) = 2.13
atan(1.50) = 0.98
cbrt(1.50) = 1.14
log2(1.50) = 0.58
floor(2.70) = 2.00
1.50 % 2.70 = 1.50

<setjmp.h>

Introduction

<setjmp.h> is a header file in the C standard library. It provides a non-local jump mechanism, allowing the program to set a jump point in a function and jump to that point in another function. .

library variables

<setjmp.h> The header file does not define any variables. Only the jmp_buf type is defined as the parameter type for the setjmp and longjmp functions. jmp_buf is an array type used to store jump point information. The specific implementation details are undefined, and it is usually implemented by the compiler as a large enough array.

Please note that although there are no variables defined in <setjmp.h>, you can create your own jmp_buf variable in your program and pass it to the setjmp and longjmp functions to implement non-local jumps.

Library Functions

<setjmp.h> Two functions are defined in the header file: setjmp and longjmp, which are used to implement non-local jumps and exception handling mechanisms.

1. int setjmp(jmp_buf env) function

  • This function saves the current execution state of the place where it is called in env and returns 0. If setjmp jumps back from longjmp, a non-zero value is returned.

2. void longjmp(jmp_buf env, int val) function

  • This function restores the corresponding execution state and jumps to the corresponding location based on the passed env parameter. The val parameter is the return value returned to setjmp.

Together, these two functions provide a very useful exception handling mechanism, often used to handle errors or exceptions, and to implement exception handling-like functionality in programs.

When using the <setjmp.h> header file, you need to pay attention to the following points:

  • setjmp and longjmp must be used in the same function call chain, and setjmp must be called before longjmp.
  • The jmp_buf type is an array type that stores information used to save execution status. However, the specific implementation details are undefined, so members of jmp_buf cannot be accessed directly.
  • Setjmp and longjmp should be used with caution because they can complicate the control flow of a program and may make the code harder to understand and maintain.

It should be noted that the <setjmp.h> header file provides a very low-level programming mechanism and is generally not recommended for frequent use.

Example

#include <stdio.h>
#include <setjmp.h>

jmp_buf exception_env; // 用于保存执行状态的全局变量

void handle_exception() {
    printf("捕获到异常,进行异常处理\n");
}

void do_something_dangerous(int input) {
    if (input < 0) {
        longjmp(exception_env, 1); // 跳转到异常处理代码
    } else {
        printf("正常处理输入:%d\n", input);
    }
}

int main() {
    if (setjmp(exception_env) == 0) { // 设置异常跳转点
        // 正常情况
        do_something_dangerous(10);
        do_something_dangerous(-5); // 这里会触发异常
        do_something_dangerous(20); // 这里不会执行
    } else {
        // 异常处理
        handle_exception();
    }

    return 0;
}

Let's compile and run the above program, which will produce the following results:

正常处理输入:10
捕获到异常,进行异常处理

This example defines a global jmp_buf type variable exception_env, which is used to save execution status. In the main function, an exception jump point is set through setjmp, and the input is judged in the do_something_dangerous function. If the input is less than 0, longjmp is called to jump to the exception handling code. After jumping back, the program can perform corresponding exception handling.

It should be noted that setjmp and longjmp are relatively low-level mechanisms, and you need to be particularly careful when using them, because they will complicate the control flow of the program and easily introduce errors that are difficult to debug.

おすすめ

転載: blog.csdn.net/m0_74293254/article/details/134548664