mirror of
https://gitee.com/Lamdonn/varch.git
synced 2025-12-06 16:56:42 +08:00
195 lines
8.8 KiB
C
195 lines
8.8 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.0
|
|
* \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 0
|
|
|
|
/**
|
|
* \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 floatl_from(const char *str);
|
|
floatl floatl_from_d(double value);
|
|
|
|
// 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
|
|
|