/********************************************************************************************************* * ------------------------------------------------------------------------------------------------------ * 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 #include #include #include #include #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