varch/source/07_math/floatl.h
2025-03-18 21:53:10 +08:00

197 lines
9.0 KiB
C

/*********************************************************************************************************
* ------------------------------------------------------------------------------------------------------
* file description
* ------------------------------------------------------------------------------------------------------
* \file floatl.h
* \unit floatl
* \brief This is a simple large float number calculate module for C language
* \author Lamdonn
* \version v1.1.1
* \license GPL-2.0
* \copyright Copyright (C) 2023 Lamdonn.
********************************************************************************************************/
#ifndef __floatl_H
#define __floatl_H
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include "floatl_cfg.h"
/* Version infomation */
#define FLOATL_V_MAJOR 1
#define FLOATL_V_MINOR 1
#define FLOATL_V_PATCH 1
/**
* \brief Common constant definitions
*/
#define FLOATL_INF __FLOATL_INF__
#define FLOATL_INF_N floatl_neg(__FLOATL_INF__)
#define FLOATL_NAN __FLOATL_NAN__
#define FLOATL_PI __FLOATL_CONST_PI__
#define FLOATL_E __FLOATL_CONST_E__
#define FLOATL_MIN __FLOATL_MIN__
#define FLOATL_MAX __FLOATL_MAX__
#define FLOATL_EPSILON __FLOATL_EPSILON__
#define FLOATL_CONST_PI __FLOATL_CONST_PI__
#define FLOATL_CONST_E __FLOATL_CONST_E__
#define FLOATL_CONST_0 __FLOATL_CONST_0__
#define FLOATL_CONST_1 __FLOATL_CONST_1__
#define FLOATL_CONST_10 __FLOATL_CONST_1e1__
#define FLOATL_CONST_100 __FLOATL_CONST_1e2__
#define FLOATL_CONST_1000 __FLOATL_CONST_1e3__
#define FLOATL_CONST_1e0 __FLOATL_CONST_1e0__
#define FLOATL_CONST_1e1 __FLOATL_CONST_1e1__
#define FLOATL_CONST_1e2 __FLOATL_CONST_1e2__
#define FLOATL_CONST_1e3 __FLOATL_CONST_1e3__
#define FLOATL_CONST_1e4 __FLOATL_CONST_1e4__
#define FLOATL_CONST_1e5 __FLOATL_CONST_1e5__
#define FLOATL_CONST_1e6 __FLOATL_CONST_1e6__
#define FLOATL_CONST_1e7 __FLOATL_CONST_1e7__
#define FLOATL_CONST_1e8 __FLOATL_CONST_1e8__
#define FLOATL_CONST_1e9 __FLOATL_CONST_1e9__
#define FLOATL_CONST_1e10 __FLOATL_CONST_1e10__
#define FLOATL_CONST_1e11 __FLOATL_CONST_1e11__
#define FLOATL_CONST_1e12 __FLOATL_CONST_1e12__
#define FLOATL_CONST_1e13 __FLOATL_CONST_1e13__
#define FLOATL_CONST_1e14 __FLOATL_CONST_1e14__
#define FLOATL_CONST_1e15 __FLOATL_CONST_1e15__
#define FLOATL_MANT_DIG __FLOATL_MANT_DIG__
#define FLOATL_MIN_EXP __FLOATL_MIN_EXP__
#define FLOATL_MAX_EXP __FLOATL_MAX_EXP__
#define FLOATL_DIG __FLOATL_DIG__
#define FLOATL_DECIMAL_DIG __FLOATL_DECIMAL_DIG__
#define FLOATL_MIN_10_EXP __FLOATL_MIN_10_EXP__
#define FLOATL_MAX_10_EXP __FLOATL_MAX_10_EXP__
/**
* \brief A structure to represent a long bits integer.
*
* This structure uses a union to store the long bits integer in two different ways:
* - An array of `__FLOATL_U16_PARTS__` uint16_t values, allowing for operations on individual 16-bit segments.
* - An array of `__FLOATL_U32_PARTS__` uint32_t values, providing a way to work with 32-bit segments.
*
* The union allows for flexibility in how the data is accessed and manipulated,
* depending on the needs of the operations being performed.
*/
typedef struct {
union {
uint16_t u16[__FLOATL_U16_PARTS__]; ///< Array of uint16_t values representing the long bit integer in 16-bit segments.
uint32_t u32[__FLOATL_U32_PARTS__]; ///< Array of uint32_t values representing the long bit integer in 32-bit segments.
struct {
uint32_t mantissas[__FLOATL_MANT_PARTS__];
uint32_t mantissa : __FLOATL_MANT_HIGH_BITS__;
uint32_t exponent : __FLOATL_EXP_BITS__;
uint32_t sign : 1;
};
};
} floatl;
/**
* \brief floatl large integer api declaration, support for basic addition, subtraction, multiplication, division, etc.
*/
// Comparison functions
// floatl_eq: Checks if two floatl numbers are equal
// floatl_ne: Checks if two floatl numbers are not equal
// floatl_lt: Checks if the first floatl number is less than the second
// floatl_le: Checks if the first floatl number is less than or equal to the second
// floatl_gt: Checks if the first floatl number is greater than the second
// floatl_ge: Checks if the first floatl number is greater than or equal to the second
int floatl_eq(floatl a, floatl b);
int floatl_ne(floatl a, floatl b);
int floatl_lt(floatl a, floatl b);
int floatl_le(floatl a, floatl b);
int floatl_gt(floatl a, floatl b);
int floatl_ge(floatl a, floatl b);
// Arithmetic operation functions
// floatl_add: Performs addition of two floatl numbers, equivalent to the '+' operator
// floatl_sub: Performs subtraction of two floatl numbers, equivalent to the '-' operator
// floatl_mul: Performs multiplication of two floatl numbers, equivalent to the '*' operator
// floatl_div: Performs division of two floatl numbers, equivalent to the '/' operator
floatl floatl_add(floatl a, floatl b);
floatl floatl_sub(floatl a, floatl b);
floatl floatl_mul(floatl a, floatl b);
floatl floatl_div(floatl a, floatl b);
// Attribute checking functions
// floatl_sign: Determines the sign of a floatl number (returns 1 for positive, -1 for negative, 0 for zero)
// floatl_isnan: Checks if a floatl number is NaN (Not a Number)
// floatl_isinf: Checks if a floatl number is infinite
// floatl_isnormal: Checks if a floatl number is a normal number (not zero, NaN, or infinite)
int floatl_sign(floatl a);
int floatl_isnan(floatl a);
int floatl_isinf(floatl a);
int floatl_isnormal(floatl a);
// Value modification functions
// floatl_abs: Computes the absolute value of a floatl number
// floatl_neg: Computes the negation of a floatl number, equivalent to the unary '-' operator
// floatl_ceil: Computes the ceiling value of a floatl number
// floatl_floor: Computes the floor value of a floatl number
// floatl_round: Computes the round value of a floatl number
floatl floatl_abs(floatl a);
floatl floatl_neg(floatl a);
floatl floatl_ceil(floatl a);
floatl floatl_floor(floatl a);
floatl floatl_round(floatl a);
// Conversion functions
// floatl_from: Converts a string to a floatl number
// floatl_from_d: Converts a double-precision floating-point number (double) to a floatl number
// floatl_to_d: Converts a floatl to a double-precision floating-point number (double) number
floatl floatl_from(const char *str);
floatl floatl_from_d(double value);
double floatl_to_d(floatl a);
// Output function
// Converts a floatl number to a string according to the specified format and stores it in the buffer
int floatl_print(floatl a, char *buffer, uint32_t size, const char *format);
/**
* \brief Converts an integer to a 'floatl' number.
*
* This macro provides a convenient way to convert an integer value to a 'floatl' type number.
* It simply calls the 'floatl_from_d' function, which is assumed to be defined elsewhere,
* to perform the actual conversion.
*
* \param[in] value: The integer value to be converted to a 'floatl' number.
* \return The corresponding 'floatl' number initialized with the given integer value.
*/
#define floatl(value) floatl_from_d(value)
/**
* \brief A macro to convert a 'floatl' number to a string and handle potential conversion errors.
*
* This macro uses the 'floatl_print' function to convert a 'floatl' number 'a' to a string and
* store it in the buffer 'b' with a given buffer size 's' according to the format string 'f'.
* If the conversion is successful (i.e., 'floatl_print' returns a value greater than 0), it returns
* the pointer to the buffer 'b' containing the converted string. Otherwise, it returns the string
* "invalid" to indicate that the conversion was not successful.
*
* \param a: The 'floatl' number to be converted.
* \param b: A pointer to the buffer where the converted string will be stored.
* \param s: The size of the buffer 'b'.
* \param f: A printf-like format string specifying how the 'floatl' number should be formatted.
* \return A pointer to the buffer 'b' if the conversion is successful; otherwise, a pointer to the
* string literal "invalid".
*/
#define floatl_show(a, b, s, f) (floatl_print((a), (b), (s), (f)) > 0 ? (b) : "invalid")
#endif