Skip to content

Float

Float

Description

Decimal arbitrary-precision floating-point value. The number represented is (-1)^negative * significand * 10^exponent.

Fields

Name Description
negative Sign flag. Zero is always normalized to non-negative.
significand Integer significand stored without decimal point.
exponent Base-10 exponent applied to the significand.

Usage example (from documentation)

  Float value = FloatFromStr("12.5");

Usage example (Cross-references)

Usage examples (Cross-references)
    }
    
    static Str FloatFmtToDecimalStr(Float *value, u32 precision, bool has_precision) {
        Str canonical = FloatToStr(value);
    }
    
    static Str FloatFmtToScientificStr(Float *value, u32 precision, bool has_precision, bool uppercase) {
        Str digits = IntToStr(&value->significand);
        Str result = StrInit();
    }
    
    void _write_Float(Str *o, FmtInfo *fmt_info, Float *value) {
        size start_len = 0;
        Str  temp      = StrInit();
    
        if (FloatFmtUsesUnsupportedFlags(fmt_info)) {
            LOG_FATAL("Float only supports decimal and scientific formatting");
        }
    }
    
    const char *_read_Float(const char *i, FmtInfo *fmt_info, Float *value) {
        size        token_len = 0;
        const char *start     = NULL;
        const char *start     = NULL;
        Str         temp      = StrInit();
        Float       parsed    = FloatInit();
    
        if (!i || !value) {
    
        if (FloatFmtUsesUnsupportedFlags(fmt_info)) {
            LOG_ERROR("Float only supports decimal and scientific reading");
            return i;
        }
    
        if (!*i) {
            LOG_ERROR("Failed to parse Float: empty input");
            return i;
        }
    
        if (token_len == 0) {
            LOG_ERROR("Failed to parse Float");
            return start;
        }
    /// Arbitrary-precision decimal floating-point implementation built on top of Int.
    
    #include <Misra/Std/Container/Float.h>
    #include <Misra/Std/Container/Int.h>
    #include <Misra/Std/Log.h>
    #include <string.h>
    
    static void float_normalize(Float *value);
    static void float_replace(Float *dst, Float *src);
    static Int  float_pow10(u64 power);
    
    static void float_normalize(Float *value);
    static void float_replace(Float *dst, Float *src);
    static Int  float_pow10(u64 power);
    static void float_scale_to_exponent(Float *value, i64 target_exponent);
    static void float_replace(Float *dst, Float *src);
    static Int  float_pow10(u64 power);
    static void float_scale_to_exponent(Float *value, i64 target_exponent);
    static int  float_abs_compare(Float *lhs, Float *rhs);
    static i64  float_add_i64_checked(i64 a, i64 b);
    static Int  float_pow10(u64 power);
    static void float_scale_to_exponent(Float *value, i64 target_exponent);
    static int  float_abs_compare(Float *lhs, Float *rhs);
    static i64  float_add_i64_checked(i64 a, i64 b);
    static i64  float_sub_i64_checked(i64 a, i64 b);
    static i64  float_add_i64_checked(i64 a, i64 b);
    static i64  float_sub_i64_checked(i64 a, i64 b);
    static Float float_from_f32_value(float value);
    static Float float_from_f64_value(double value);
    static i64  float_sub_i64_checked(i64 a, i64 b);
    static Float float_from_f32_value(float value);
    static Float float_from_f64_value(double value);
    
    static i64 float_add_i64_checked(i64 a, i64 b) {
    static i64 float_add_i64_checked(i64 a, i64 b) {
        if ((b > 0 && a > INT64_MAX - b) || (b < 0 && a < INT64_MIN - b)) {
            LOG_FATAL("Float exponent overflow");
        }
    static i64 float_sub_i64_checked(i64 a, i64 b) {
        if ((b > 0 && a < INT64_MIN + b) || (b < 0 && a > INT64_MAX + b)) {
            LOG_FATAL("Float exponent overflow");
        }
    }
    
    static Float float_from_f32_value(float value) {
        char text[32] = {0};
        int  len      = snprintf(text, sizeof(text), "%.9g", (double)value);
    
        if (len < 0 || len >= (int)sizeof(text)) {
            LOG_FATAL("Failed to convert f32 to Float");
        }
    }
    
    static Float float_from_f64_value(double value) {
        char text[48] = {0};
        int  len      = snprintf(text, sizeof(text), "%.17g", value);
    
        if (len < 0 || len >= (int)sizeof(text)) {
            LOG_FATAL("Failed to convert f64 to Float");
        }
    }
    
    static void float_replace(Float *dst, Float *src) {
        FloatDeinit(dst);
        *dst = *src;
    }
    
    static void float_scale_to_exponent(Float *value, i64 target_exponent) {
        ValidateFloat(value);
    }
    
    static int float_abs_compare(Float *lhs, Float *rhs) {
        ValidateFloat(lhs);
        ValidateFloat(rhs);
        {
            i64   target_exponent = lhs->exponent < rhs->exponent ? lhs->exponent : rhs->exponent;
            Float lhs_scaled      = FloatClone(lhs);
            Float rhs_scaled      = FloatClone(rhs);
            int   cmp             = 0;
            i64   target_exponent = lhs->exponent < rhs->exponent ? lhs->exponent : rhs->exponent;
            Float lhs_scaled      = FloatClone(lhs);
            Float rhs_scaled      = FloatClone(rhs);
            int   cmp             = 0;
    }
    
    static void float_normalize(Float *value) {
        ValidateFloat(value);
    }
    
    bool FloatIsZero(Float *value) {
        ValidateFloat(value);
        return IntIsZero(&value->significand);
    }
    
    bool FloatIsNegative(Float *value) {
        ValidateFloat(value);
        return !FloatIsZero(value) && value->negative;
    }
    
    i64 FloatExponent(Float *value) {
        ValidateFloat(value);
        return value->exponent;
    }
    
    Float FloatClone(Float *value) {
        Float clone = FloatInit();
    
    Float FloatClone(Float *value) {
        Float clone = FloatInit();
    
        ValidateFloat(value);
    }
    
    Float MISRA_PRIV_FloatFromU64(u64 value) {
        Float result = FloatInit();
    
    Float MISRA_PRIV_FloatFromU64(u64 value) {
        Float result = FloatInit();
    
        result.significand = MISRA_PRIV_IntFromU64(value);
    }
    
    Float MISRA_PRIV_FloatFromI64(i64 value) {
        Float result    = FloatInit();
        u64   magnitude = 0;
    
    Float MISRA_PRIV_FloatFromI64(i64 value) {
        Float result    = FloatInit();
        u64   magnitude = 0;
    }
    
    Float MISRA_PRIV_FloatFromInt(Int *value) {
        Float result = FloatInit();
    
    Float MISRA_PRIV_FloatFromInt(Int *value) {
        Float result = FloatInit();
    
        ValidateInt(value);
    }
    
    Float MISRA_PRIV_FloatFromF32(float value) {
        return float_from_f32_value(value);
    }
    }
    
    Float MISRA_PRIV_FloatFromF64(double value) {
        return float_from_f64_value(value);
    }
    }
    
    bool FloatToInt(Int *result, Float *value) {
        Int temp = IntInit();
    }
    
    Float FloatFromStr(const char *text) {
        Float result          = FloatInit();
        Str   digits          = StrInit();
    
    Float FloatFromStr(const char *text) {
        Float result          = FloatInit();
        Str   digits          = StrInit();
        size  pos             = 0;
            if (ch == '.') {
                if (saw_decimal) {
                    LOG_FATAL("Invalid Float format");
                }
                pos++;
                if (text[pos] == '\0') {
                    LOG_FATAL("Invalid Float exponent");
                }
                parsed = strtoll(text + pos, &endptr, 10);
                if (errno == ERANGE || endptr == text + pos || *endptr != '\0') {
                    LOG_FATAL("Invalid Float exponent");
                }
            }
    
            LOG_FATAL("Invalid Float format");
        }
    
        if (!saw_digit) {
            LOG_FATAL("Invalid Float format");
        }
    }
    
    Str FloatToStr(Float *value) {
        Str digits = StrInit();
        Str result = StrInit();
    }
    
    int(FloatCompare)(Float *lhs, Float *rhs) {
        int cmp = 0;
    }
    
    int MISRA_PRIV_FloatCompareInt(Float *lhs, Int *rhs) {
        Float rhs_value = MISRA_PRIV_FloatFromInt(rhs);
        int   cmp       = FloatCompare(lhs, &rhs_value);
    
    int MISRA_PRIV_FloatCompareInt(Float *lhs, Int *rhs) {
        Float rhs_value = MISRA_PRIV_FloatFromInt(rhs);
        int   cmp       = FloatCompare(lhs, &rhs_value);
    }
    
    int MISRA_PRIV_FloatCompareU64(Float *lhs, u64 rhs) {
        Float rhs_value = MISRA_PRIV_FloatFromU64(rhs);
        int   cmp       = FloatCompare(lhs, &rhs_value);
    
    int MISRA_PRIV_FloatCompareU64(Float *lhs, u64 rhs) {
        Float rhs_value = MISRA_PRIV_FloatFromU64(rhs);
        int   cmp       = FloatCompare(lhs, &rhs_value);
    }
    
    int MISRA_PRIV_FloatCompareI64(Float *lhs, i64 rhs) {
        Float rhs_value = MISRA_PRIV_FloatFromI64(rhs);
        int   cmp       = FloatCompare(lhs, &rhs_value);
    
    int MISRA_PRIV_FloatCompareI64(Float *lhs, i64 rhs) {
        Float rhs_value = MISRA_PRIV_FloatFromI64(rhs);
        int   cmp       = FloatCompare(lhs, &rhs_value);
    }
    
    int MISRA_PRIV_FloatCompareF32(Float *lhs, float rhs) {
        Float rhs_value = float_from_f32_value(rhs);
        int   cmp       = FloatCompare(lhs, &rhs_value);
    
    int MISRA_PRIV_FloatCompareF32(Float *lhs, float rhs) {
        Float rhs_value = float_from_f32_value(rhs);
        int   cmp       = FloatCompare(lhs, &rhs_value);
    }
    
    int MISRA_PRIV_FloatCompareF64(Float *lhs, double rhs) {
        Float rhs_value = float_from_f64_value(rhs);
        int   cmp       = FloatCompare(lhs, &rhs_value);
    
    int MISRA_PRIV_FloatCompareF64(Float *lhs, double rhs) {
        Float rhs_value = float_from_f64_value(rhs);
        int   cmp       = FloatCompare(lhs, &rhs_value);
    }
    
    void FloatNegate(Float *value) {
        ValidateFloat(value);
    }
    
    void FloatAbs(Float *value) {
        ValidateFloat(value);
        value->negative = false;
    }
    
    void(FloatAdd)(Float *result, Float *a, Float *b) {
        Float lhs  = FloatClone(a);
        Float rhs  = FloatClone(b);
    
    void(FloatAdd)(Float *result, Float *a, Float *b) {
        Float lhs  = FloatClone(a);
        Float rhs  = FloatClone(b);
        Float temp = FloatInit();
    void(FloatAdd)(Float *result, Float *a, Float *b) {
        Float lhs  = FloatClone(a);
        Float rhs  = FloatClone(b);
        Float temp = FloatInit();
        i64   exp  = 0;
        Float lhs  = FloatClone(a);
        Float rhs  = FloatClone(b);
        Float temp = FloatInit();
        i64   exp  = 0;
    }
    
    void MISRA_PRIV_FloatAddInt(Float *result, Float *a, Int *b) {
        Float rhs = MISRA_PRIV_FloatFromInt(b);
    
    void MISRA_PRIV_FloatAddInt(Float *result, Float *a, Int *b) {
        Float rhs = MISRA_PRIV_FloatFromInt(b);
    
        FloatAdd(result, a, &rhs);
    }
    
    void MISRA_PRIV_FloatAddU64(Float *result, Float *a, u64 b) {
        Float rhs = MISRA_PRIV_FloatFromU64(b);
    
    void MISRA_PRIV_FloatAddU64(Float *result, Float *a, u64 b) {
        Float rhs = MISRA_PRIV_FloatFromU64(b);
    
        FloatAdd(result, a, &rhs);
    }
    
    void MISRA_PRIV_FloatAddI64(Float *result, Float *a, i64 b) {
        Float rhs = MISRA_PRIV_FloatFromI64(b);
    
    void MISRA_PRIV_FloatAddI64(Float *result, Float *a, i64 b) {
        Float rhs = MISRA_PRIV_FloatFromI64(b);
    
        FloatAdd(result, a, &rhs);
    }
    
    void MISRA_PRIV_FloatAddF32(Float *result, Float *a, float b) {
        Float rhs = float_from_f32_value(b);
    
    void MISRA_PRIV_FloatAddF32(Float *result, Float *a, float b) {
        Float rhs = float_from_f32_value(b);
    
        FloatAdd(result, a, &rhs);
    }
    
    void MISRA_PRIV_FloatAddF64(Float *result, Float *a, double b) {
        Float rhs = float_from_f64_value(b);
    
    void MISRA_PRIV_FloatAddF64(Float *result, Float *a, double b) {
        Float rhs = float_from_f64_value(b);
    
        FloatAdd(result, a, &rhs);
    }
    
    void(FloatSub)(Float *result, Float *a, Float *b) {
        Float rhs = FloatClone(b);
    
    void(FloatSub)(Float *result, Float *a, Float *b) {
        Float rhs = FloatClone(b);
    
        ValidateFloat(result);
    }
    
    void MISRA_PRIV_FloatSubInt(Float *result, Float *a, Int *b) {
        Float rhs = MISRA_PRIV_FloatFromInt(b);
    
    void MISRA_PRIV_FloatSubInt(Float *result, Float *a, Int *b) {
        Float rhs = MISRA_PRIV_FloatFromInt(b);
    
        FloatSub(result, a, &rhs);
    }
    
    void MISRA_PRIV_FloatSubU64(Float *result, Float *a, u64 b) {
        Float rhs = MISRA_PRIV_FloatFromU64(b);
    
    void MISRA_PRIV_FloatSubU64(Float *result, Float *a, u64 b) {
        Float rhs = MISRA_PRIV_FloatFromU64(b);
    
        FloatSub(result, a, &rhs);
    }
    
    void MISRA_PRIV_FloatSubI64(Float *result, Float *a, i64 b) {
        Float rhs = MISRA_PRIV_FloatFromI64(b);
    
    void MISRA_PRIV_FloatSubI64(Float *result, Float *a, i64 b) {
        Float rhs = MISRA_PRIV_FloatFromI64(b);
    
        FloatSub(result, a, &rhs);
    }
    
    void MISRA_PRIV_FloatSubF32(Float *result, Float *a, float b) {
        Float rhs = float_from_f32_value(b);
    
    void MISRA_PRIV_FloatSubF32(Float *result, Float *a, float b) {
        Float rhs = float_from_f32_value(b);
    
        FloatSub(result, a, &rhs);
    }
    
    void MISRA_PRIV_FloatSubF64(Float *result, Float *a, double b) {
        Float rhs = float_from_f64_value(b);
    
    void MISRA_PRIV_FloatSubF64(Float *result, Float *a, double b) {
        Float rhs = float_from_f64_value(b);
    
        FloatSub(result, a, &rhs);
    }
    
    void(FloatMul)(Float *result, Float *a, Float *b) {
        Float temp = FloatInit();
    
    void(FloatMul)(Float *result, Float *a, Float *b) {
        Float temp = FloatInit();
    
        ValidateFloat(result);
    }
    
    void MISRA_PRIV_FloatMulInt(Float *result, Float *a, Int *b) {
        Float rhs = MISRA_PRIV_FloatFromInt(b);
    
    void MISRA_PRIV_FloatMulInt(Float *result, Float *a, Int *b) {
        Float rhs = MISRA_PRIV_FloatFromInt(b);
    
        FloatMul(result, a, &rhs);
    }
    
    void MISRA_PRIV_FloatMulU64(Float *result, Float *a, u64 b) {
        Float rhs = MISRA_PRIV_FloatFromU64(b);
    
    void MISRA_PRIV_FloatMulU64(Float *result, Float *a, u64 b) {
        Float rhs = MISRA_PRIV_FloatFromU64(b);
    
        FloatMul(result, a, &rhs);
    }
    
    void MISRA_PRIV_FloatMulI64(Float *result, Float *a, i64 b) {
        Float rhs = MISRA_PRIV_FloatFromI64(b);
    
    void MISRA_PRIV_FloatMulI64(Float *result, Float *a, i64 b) {
        Float rhs = MISRA_PRIV_FloatFromI64(b);
    
        FloatMul(result, a, &rhs);
    }
    
    void MISRA_PRIV_FloatMulF32(Float *result, Float *a, float b) {
        Float rhs = float_from_f32_value(b);
    
    void MISRA_PRIV_FloatMulF32(Float *result, Float *a, float b) {
        Float rhs = float_from_f32_value(b);
    
        FloatMul(result, a, &rhs);
    }
    
    void MISRA_PRIV_FloatMulF64(Float *result, Float *a, double b) {
        Float rhs = float_from_f64_value(b);
    
    void MISRA_PRIV_FloatMulF64(Float *result, Float *a, double b) {
        Float rhs = float_from_f64_value(b);
    
        FloatMul(result, a, &rhs);
    }
    
    void(FloatDiv)(Float *result, Float *a, Float *b, u64 precision) {
        Float temp   = FloatInit();
        Int   scale  = IntInit();
    
    void(FloatDiv)(Float *result, Float *a, Float *b, u64 precision) {
        Float temp   = FloatInit();
        Int   scale  = IntInit();
        Int   scaled = IntInit();
        }
        if (FloatIsZero(a)) {
            Float zero = FloatInit();
            float_replace(result, &zero);
            return;
    }
    
    void MISRA_PRIV_FloatDivInt(Float *result, Float *a, Int *b, u64 precision) {
        Float rhs = MISRA_PRIV_FloatFromInt(b);
    
    void MISRA_PRIV_FloatDivInt(Float *result, Float *a, Int *b, u64 precision) {
        Float rhs = MISRA_PRIV_FloatFromInt(b);
    
        FloatDiv(result, a, &rhs, precision);
    }
    
    void MISRA_PRIV_FloatDivU64(Float *result, Float *a, u64 b, u64 precision) {
        Float rhs = MISRA_PRIV_FloatFromU64(b);
    
    void MISRA_PRIV_FloatDivU64(Float *result, Float *a, u64 b, u64 precision) {
        Float rhs = MISRA_PRIV_FloatFromU64(b);
    
        FloatDiv(result, a, &rhs, precision);
    }
    
    void MISRA_PRIV_FloatDivI64(Float *result, Float *a, i64 b, u64 precision) {
        Float rhs = MISRA_PRIV_FloatFromI64(b);
    
    void MISRA_PRIV_FloatDivI64(Float *result, Float *a, i64 b, u64 precision) {
        Float rhs = MISRA_PRIV_FloatFromI64(b);
    
        FloatDiv(result, a, &rhs, precision);
    }
    
    void MISRA_PRIV_FloatDivF32(Float *result, Float *a, float b, u64 precision) {
        Float rhs = float_from_f32_value(b);
    
    void MISRA_PRIV_FloatDivF32(Float *result, Float *a, float b, u64 precision) {
        Float rhs = float_from_f32_value(b);
    
        FloatDiv(result, a, &rhs, precision);
    }
    
    void MISRA_PRIV_FloatDivF64(Float *result, Float *a, double b, u64 precision) {
        Float rhs = float_from_f64_value(b);
    
    void MISRA_PRIV_FloatDivF64(Float *result, Float *a, double b, u64 precision) {
        Float rhs = float_from_f64_value(b);
    
        FloatDiv(result, a, &rhs, precision);
    #include <Misra/Std/Container/Float.h>
    #include <Misra/Std/Container/Int.h>
    #include <Misra/Std/Log.h>
        WriteFmt("Testing FloatNegate and FloatAbs\n");
    
        Float value = FloatFromStr("12.5");
        Str   text  = StrInit();
        WriteFmt("Testing FloatAdd with small floats\n");
    
        Float a            = FloatFromStr("1.2");
        Float b            = FloatFromStr("0.03");
        Float result_value = FloatInit();
    
        Float a            = FloatFromStr("1.2");
        Float b            = FloatFromStr("0.03");
        Float result_value = FloatInit();
        Str   text         = StrInit();
        Float a            = FloatFromStr("1.2");
        Float b            = FloatFromStr("0.03");
        Float result_value = FloatInit();
        Str   text         = StrInit();
        WriteFmt("Testing FloatAdd with very large floats\n");
    
        Float a            = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES);
        Float b            = FloatFromStr(FLOAT_TEST_VERY_LARGE_TWOS);
        Float result_value = FloatInit();
    
        Float a            = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES);
        Float b            = FloatFromStr(FLOAT_TEST_VERY_LARGE_TWOS);
        Float result_value = FloatInit();
        Str   text         = StrInit();
        Float a            = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES);
        Float b            = FloatFromStr(FLOAT_TEST_VERY_LARGE_TWOS);
        Float result_value = FloatInit();
        Str   text         = StrInit();
        WriteFmt("Testing FloatAdd generic dispatch\n");
    
        Float a            = FloatFromStr("1.25");
        Float b            = FloatFromStr("0.75");
        Int   whole        = IntFrom(2);
    
        Float a            = FloatFromStr("1.25");
        Float b            = FloatFromStr("0.75");
        Int   whole        = IntFrom(2);
        Float result_value = FloatInit();
        Float b            = FloatFromStr("0.75");
        Int   whole        = IntFrom(2);
        Float result_value = FloatInit();
        Str   text         = StrInit();
        WriteFmt("Testing FloatSub with small floats\n");
    
        Float a            = FloatFromStr("1.5");
        Float b            = FloatFromStr("2");
        Float result_value = FloatInit();
    
        Float a            = FloatFromStr("1.5");
        Float b            = FloatFromStr("2");
        Float result_value = FloatInit();
        Str   text         = StrInit();
        Float a            = FloatFromStr("1.5");
        Float b            = FloatFromStr("2");
        Float result_value = FloatInit();
        Str   text         = StrInit();
        WriteFmt("Testing FloatSub with very large floats\n");
    
        Float a            = FloatFromStr(FLOAT_TEST_VERY_LARGE_THREES);
        Float b            = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES);
        Float result_value = FloatInit();
    
        Float a            = FloatFromStr(FLOAT_TEST_VERY_LARGE_THREES);
        Float b            = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES);
        Float result_value = FloatInit();
        Str   text         = StrInit();
        Float a            = FloatFromStr(FLOAT_TEST_VERY_LARGE_THREES);
        Float b            = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES);
        Float result_value = FloatInit();
        Str   text         = StrInit();
        WriteFmt("Testing FloatSub generic dispatch\n");
    
        Float a            = FloatFromStr("5.5");
        Float b            = FloatFromStr("0.5");
        Int   whole        = IntFrom(2);
    
        Float a            = FloatFromStr("5.5");
        Float b            = FloatFromStr("0.5");
        Int   whole        = IntFrom(2);
        Float result_value = FloatInit();
        Float b            = FloatFromStr("0.5");
        Int   whole        = IntFrom(2);
        Float result_value = FloatInit();
        Str   text         = StrInit();
        WriteFmt("Testing FloatMul with small floats\n");
    
        Float a            = FloatFromStr("12.5");
        Float b            = FloatFromStr("-0.2");
        Float result_value = FloatInit();
    
        Float a            = FloatFromStr("12.5");
        Float b            = FloatFromStr("-0.2");
        Float result_value = FloatInit();
        Str   text         = StrInit();
        Float a            = FloatFromStr("12.5");
        Float b            = FloatFromStr("-0.2");
        Float result_value = FloatInit();
        Str   text         = StrInit();
        WriteFmt("Testing FloatMul with very large and small floats\n");
    
        Float a            = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES);
        Float b            = FloatFromStr("2");
        Float result_value = FloatInit();
    
        Float a            = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES);
        Float b            = FloatFromStr("2");
        Float result_value = FloatInit();
        Str   text         = StrInit();
        Float a            = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES);
        Float b            = FloatFromStr("2");
        Float result_value = FloatInit();
        Str   text         = StrInit();
        WriteFmt("Testing FloatMul generic dispatch\n");
    
        Float a            = FloatFromStr("1.5");
        Float b            = FloatFromStr("2");
        Int   whole        = IntFrom(2);
    
        Float a            = FloatFromStr("1.5");
        Float b            = FloatFromStr("2");
        Int   whole        = IntFrom(2);
        Float result_value = FloatInit();
        Float b            = FloatFromStr("2");
        Int   whole        = IntFrom(2);
        Float result_value = FloatInit();
        Str   text         = StrInit();
        WriteFmt("Testing FloatDiv with small floats\n");
    
        Float a            = FloatFromStr("1");
        Float b            = FloatFromStr("8");
        Float result_value = FloatInit();
    
        Float a            = FloatFromStr("1");
        Float b            = FloatFromStr("8");
        Float result_value = FloatInit();
        Str   text         = StrInit();
        Float a            = FloatFromStr("1");
        Float b            = FloatFromStr("8");
        Float result_value = FloatInit();
        Str   text         = StrInit();
        WriteFmt("Testing FloatDiv with very large and small floats\n");
    
        Float a            = FloatFromStr(FLOAT_TEST_VERY_LARGE_TWOS);
        Float b            = FloatFromStr("2");
        Float result_value = FloatInit();
    
        Float a            = FloatFromStr(FLOAT_TEST_VERY_LARGE_TWOS);
        Float b            = FloatFromStr("2");
        Float result_value = FloatInit();
        Str   text         = StrInit();
        Float a            = FloatFromStr(FLOAT_TEST_VERY_LARGE_TWOS);
        Float b            = FloatFromStr("2");
        Float result_value = FloatInit();
        Str   text         = StrInit();
        WriteFmt("Testing FloatDiv generic dispatch\n");
    
        Float a            = FloatFromStr("7.5");
        Float b            = FloatFromStr("2.5");
        Int   whole        = IntFrom(3);
    
        Float a            = FloatFromStr("7.5");
        Float b            = FloatFromStr("2.5");
        Int   whole        = IntFrom(3);
        Float result_value = FloatInit();
        Float b            = FloatFromStr("2.5");
        Int   whole        = IntFrom(3);
        Float result_value = FloatInit();
        Str   text         = StrInit();
        WriteFmt("Testing FloatDiv divide-by-zero handling\n");
    
        Float a = FloatFromStr("1");
        Float b = FloatInit();
        Float r = FloatInit();
    
        Float a = FloatFromStr("1");
        Float b = FloatInit();
        Float r = FloatInit();
        Float a = FloatFromStr("1");
        Float b = FloatInit();
        Float r = FloatInit();
    
        FloatDiv(&r, &a, &b, 4);
    
    int main(void) {
        WriteFmt("[INFO] Starting Float.Math tests\n\n");
    
        TestFunction tests[] = {
        int total_deadend_tests = sizeof(deadend_tests) / sizeof(deadend_tests[0]);
    
        return run_test_suite(tests, total_tests, deadend_tests, total_deadend_tests, "Float.Math");
    }
    
    bool test_float_reading(void) {
        WriteFmt("Testing Float reading\n");
    
        const char *z = NULL;
        bool        success = true;
    
        Float dec = FloatInit();
        Float sci = FloatInit();
        Float neg = FloatInit();
    
        Float dec = FloatInit();
        Float sci = FloatInit();
        Float neg = FloatInit();
        Float dec = FloatInit();
        Float sci = FloatInit();
        Float neg = FloatInit();
    
        Str dec_text = StrInit();
    #include <Misra/Std/Container/Float.h>
    #include <Misra/Std/Container/Int.h>
    #include <Misra/Std/Log.h>
        WriteFmt("Testing FloatCompare with small floats\n");
    
        Float a = FloatFromStr("1.23");
        Float b = FloatFromStr("123e-2");
        Float c = FloatFromStr("-1.23");
    
        Float a = FloatFromStr("1.23");
        Float b = FloatFromStr("123e-2");
        Float c = FloatFromStr("-1.23");
        Float a = FloatFromStr("1.23");
        Float b = FloatFromStr("123e-2");
        Float c = FloatFromStr("-1.23");
    
        bool result = FloatCompare(&a, &b) == 0;
        WriteFmt("Testing FloatCompare with very large floats\n");
    
        Float a = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES);
        Float b = FloatFromStr(FLOAT_TEST_VERY_LARGE_TWOS);
        Float c = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES);
    
        Float a = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES);
        Float b = FloatFromStr(FLOAT_TEST_VERY_LARGE_TWOS);
        Float c = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES);
        Float a = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES);
        Float b = FloatFromStr(FLOAT_TEST_VERY_LARGE_TWOS);
        Float c = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES);
    
        bool result = FloatLT(&a, &b);
        WriteFmt("Testing FloatCompare with very large and small floats\n");
    
        Float large          = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES);
        Float negative_large = FloatFromStr("-" FLOAT_TEST_VERY_LARGE_ONES);
        Float small          = FloatFromStr("2.5");
    
        Float large          = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES);
        Float negative_large = FloatFromStr("-" FLOAT_TEST_VERY_LARGE_ONES);
        Float small          = FloatFromStr("2.5");
        Float large          = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES);
        Float negative_large = FloatFromStr("-" FLOAT_TEST_VERY_LARGE_ONES);
        Float small          = FloatFromStr("2.5");
    
        bool result = FloatGT(&large, &small);
    
    bool test_float_compare_wrappers(void) {
        WriteFmt("Testing Float compare macros\n");
    
        Float a        = FloatFromStr("-2");
        WriteFmt("Testing Float compare macros\n");
    
        Float a        = FloatFromStr("-2");
        Float b        = FloatFromStr("0.5");
        Float expected = FloatFromStr("5e-1");
    
        Float a        = FloatFromStr("-2");
        Float b        = FloatFromStr("0.5");
        Float expected = FloatFromStr("5e-1");
        Float a        = FloatFromStr("-2");
        Float b        = FloatFromStr("0.5");
        Float expected = FloatFromStr("5e-1");
    
        bool result = FloatLT(&a, &b);
        WriteFmt("Testing FloatCompare generic dispatch\n");
    
        Float value = FloatFromStr("12.5");
        Float same  = FloatFromStr("12.5");
        Int   whole = IntFrom(12);
    
        Float value = FloatFromStr("12.5");
        Float same  = FloatFromStr("12.5");
        Int   whole = IntFrom(12);
        Int   next  = IntFrom(13);
    
    int main(void) {
        WriteFmt("[INFO] Starting Float.Compare tests\n\n");
    
        TestFunction tests[] = {
    
        int total_tests = sizeof(tests) / sizeof(tests[0]);
        return run_test_suite(tests, total_tests, NULL, 0, "Float.Compare");
    }
    
    bool test_float_formatting(void) {
        WriteFmt("Testing Float formatting\n");
    
        Str   output  = StrInit();
        Str   output  = StrInit();
        bool  success = true;
        Float exact   = FloatFromStr("1234567890.012345");
        Float sci     = FloatFromStr("12345.67");
        Float short_v = FloatFromStr("1.2");
        bool  success = true;
        Float exact   = FloatFromStr("1234567890.012345");
        Float sci     = FloatFromStr("12345.67");
        Float short_v = FloatFromStr("1.2");
        Float exact   = FloatFromStr("1234567890.012345");
        Float sci     = FloatFromStr("12345.67");
        Float short_v = FloatFromStr("1.2");
    
        StrWriteFmt(&output, "{}", exact);
    #include <Misra/Std/Container/Float.h>
    #include <Misra/Std/Container/Int.h>
    #include <Misra/Std/Log.h>
        WriteFmt("Testing FloatFrom with unsigned integer\n");
    
        Float value = FloatFrom(42);
        Str   text  = FloatToStr(&value);
        WriteFmt("Testing FloatFrom with signed integer\n");
    
        Float value = FloatFrom(-42);
        Str   text  = FloatToStr(&value);
    
        Int   integer = IntFromStr("12345678901234567890");
        Float value   = FloatFrom(&integer);
        Str   text    = FloatToStr(&value);
        WriteFmt("Testing FloatToInt exact conversion\n");
    
        Float value        = FloatFromStr("1234500e-2");
        Int   result_value = IntInit();
        Str   text         = StrInit();
        WriteFmt("Testing FloatToInt fractional failure handling\n");
    
        Float value        = FloatFromStr("123.45");
        Int   result_value = IntFrom(99);
        WriteFmt("Testing FloatToInt negative failure handling\n");
    
        Float value        = FloatFromStr("-42");
        Int   result_value = IntFrom(99);
    
    bool test_float_string_round_trip(void) {
        WriteFmt("Testing Float string round trip\n");
    
        Float value = FloatFromStr("-123.45");
        WriteFmt("Testing Float string round trip\n");
    
        Float value = FloatFromStr("-123.45");
        Str   text  = FloatToStr(&value);
    
    bool test_float_very_large_string_round_trip(void) {
        WriteFmt("Testing Float very large string round trip\n");
    
        Float value = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES);
        WriteFmt("Testing Float very large string round trip\n");
    
        Float value = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES);
        Str   text  = FloatToStr(&value);
    
    bool test_float_scientific_parse(void) {
        WriteFmt("Testing Float scientific parsing\n");
    
        Float value = FloatFromStr("1.2300e3");
        WriteFmt("Testing Float scientific parsing\n");
    
        Float value = FloatFromStr("1.2300e3");
        Str   text  = FloatToStr(&value);
    
    int main(void) {
        WriteFmt("[INFO] Starting Float.Convert tests\n\n");
    
        TestFunction tests[] = {
        int total_deadend_tests = sizeof(deadend_tests) / sizeof(deadend_tests[0]);
    
        return run_test_suite(tests, total_tests, deadend_tests, total_deadend_tests, "Float.Convert");
    }
    #include <Misra/Std/Container/Float.h>
    #include <Misra/Std/Log.h>
        WriteFmt("Testing FloatIsZero\n");
    
        Float zero  = FloatInit();
        Float value = FloatFromStr("0.001");
    
        Float zero  = FloatInit();
        Float value = FloatFromStr("0.001");
    
        bool result = FloatIsZero(&zero);
        WriteFmt("Testing FloatIsNegative\n");
    
        Float neg  = FloatFromStr("-42");
        Float pos  = FloatFromStr("42");
        Float zero = FloatFromStr("-0.0");
    
        Float neg  = FloatFromStr("-42");
        Float pos  = FloatFromStr("42");
        Float zero = FloatFromStr("-0.0");
        Float neg  = FloatFromStr("-42");
        Float pos  = FloatFromStr("42");
        Float zero = FloatFromStr("-0.0");
    
        bool result = FloatIsNegative(&neg);
        WriteFmt("Testing FloatExponent\n");
    
        Float value = FloatFromStr("12.34");
    
        bool result = FloatExponent(&value) == -2;
    
    int main(void) {
        WriteFmt("[INFO] Starting Float.Access tests\n\n");
    
        TestFunction tests[] = {
    
        int total_tests = sizeof(tests) / sizeof(tests[0]);
        return run_test_suite(tests, total_tests, NULL, 0, "Float.Access");
    }
    #include <Misra/Std/Container/Float.h>
    #include <Misra/Std/Log.h>
    #include <string.h>
        WriteFmt("Testing FloatInit\n");
    
        Float value = FloatInit();
    
        bool result = FloatIsZero(&value);
        WriteFmt("Testing FloatClear\n");
    
        Float value = FloatFromStr("-123.45");
    
        FloatClear(&value);
        WriteFmt("Testing FloatClone\n");
    
        Float original = FloatFromStr("-12.5");
        Float clone    = FloatClone(&original);
        Float expected = FloatFromStr("-12.5");
    
        Float original = FloatFromStr("-12.5");
        Float clone    = FloatClone(&original);
        Float expected = FloatFromStr("-12.5");
        Str   text     = FloatToStr(&clone);
        Float original = FloatFromStr("-12.5");
        Float clone    = FloatClone(&original);
        Float expected = FloatFromStr("-12.5");
        Str   text     = FloatToStr(&clone);
    
    int main(void) {
        WriteFmt("[INFO] Starting Float.Type tests\n\n");
    
        TestFunction tests[] = {
    
        int total_tests = sizeof(tests) / sizeof(tests[0]);
        return run_test_suite(tests, total_tests, NULL, 0, "Float.Type");
    }
                TypeSpecificIO: (x),                                                                                       \
                Str: TO_TYPE_SPECIFIC_IO(Str, &(x)),                                                                       \
                Float: TO_TYPE_SPECIFIC_IO(Float, &(x)),                                                                   \
                Int: TO_TYPE_SPECIFIC_IO(Int, &(x)),                                                                       \
                BitVec: TO_TYPE_SPECIFIC_IO(BitVec, &(x)),                                                                 \
                TypeSpecificIO: (x),                                                                                       \
                Str: TO_TYPE_SPECIFIC_IO(Str, (void *)&(x)),                                                               \
                Float: TO_TYPE_SPECIFIC_IO(Float, (void *)&(x)),                                                           \
                Int: TO_TYPE_SPECIFIC_IO(Int, (void *)&(x)),                                                               \
                BitVec: TO_TYPE_SPECIFIC_IO(BitVec, (void *)&(x)),                                                         \
    void _write_f32(Str *o, FmtInfo *fmt_info, f32 *v);
    void _write_f64(Str *o, FmtInfo *fmt_info, f64 *v);
    void _write_Float(Str *o, FmtInfo *fmt_info, Float *value);
    void _write_BitVec(Str *o, FmtInfo *fmt_info, BitVec *bv);
    void _write_Int(Str *o, FmtInfo *fmt_info, Int *value);
    const char *_read_f32(const char *i, FmtInfo *fmt_info, f32 *v);
    const char *_read_f64(const char *i, FmtInfo *fmt_info, f64 *v);
    const char *_read_Float(const char *i, FmtInfo *fmt_info, Float *value);
    const char *_read_BitVec(const char *i, FmtInfo *fmt_info, BitVec *bv);
    const char *_read_Int(const char *i, FmtInfo *fmt_info, Int *value);
    #include <Misra/Std/Container/BitVec.h>
    #include <Misra/Std/Container/Int.h>
    #include <Misra/Std/Container/Float.h>
    
    #endif // MISRA_STD_CONTAINER_H
    #define MISRA_STD_CONTAINER_FLOAT_H
    
    #include "Float/Type.h"
    #include "Float/Init.h"
    #include "Float/Access.h"
    
    #include "Float/Type.h"
    #include "Float/Init.h"
    #include "Float/Access.h"
    #include "Float/Memory.h"
    #include "Float/Type.h"
    #include "Float/Init.h"
    #include "Float/Access.h"
    #include "Float/Memory.h"
    #include "Float/Convert.h"
    #include "Float/Init.h"
    #include "Float/Access.h"
    #include "Float/Memory.h"
    #include "Float/Convert.h"
    #include "Float/Private.h"
    #include "Float/Access.h"
    #include "Float/Memory.h"
    #include "Float/Convert.h"
    #include "Float/Private.h"
    #include "Float/Compare.h"
    #include "Float/Memory.h"
    #include "Float/Convert.h"
    #include "Float/Private.h"
    #include "Float/Compare.h"
    #include "Float/Math.h"
    #include "Float/Convert.h"
    #include "Float/Private.h"
    #include "Float/Compare.h"
    #include "Float/Math.h"
    #include "Float/Private.h"
    #include "Float/Compare.h"
    #include "Float/Math.h"
    
    #endif // MISRA_STD_CONTAINER_FLOAT_H
    /// TAGS: Float, Math, Negate, Sign
    ///
    void FloatNegate(Float *value);
    ///
    /// Replace a float with its absolute value.
    /// TAGS: Float, Math, AbsoluteValue
    ///
    void FloatAbs(Float *value);
    ///
    /// Add two floats.
    /// TAGS: Float, Math, Add
    ///
    void (FloatAdd)(Float *result, Float *a, Float *b);
    ///
    /// Subtract one float from another.
    /// TAGS: Float, Math, Subtract
    ///
    void (FloatSub)(Float *result, Float *a, Float *b);
    ///
    /// Multiply two floats.
    /// TAGS: Float, Math, Multiply
    ///
    void (FloatMul)(Float *result, Float *a, Float *b);
    ///
    /// Divide one float by another.
    /// TAGS: Float, Math, Divide, Precision
    ///
    void (FloatDiv)(Float *result, Float *a, Float *b, u64 precision);
    #ifndef __cplusplus
    #    define MISRA_FLOAT_ADD_DISPATCH(rhs)                                                                              \
            _Generic(                                                                                                      \
                (rhs),                                                                                                     \
                Float: MISRA_PRIV_FloatAddValueFloat,                                                                      \
                Float *: FloatAdd,                                                                                         \
                const Float *: MISRA_PRIV_FloatAddConstFloat,                                                              \
                (rhs),                                                                                                     \
                Float: MISRA_PRIV_FloatAddValueFloat,                                                                      \
                Float *: FloatAdd,                                                                                         \
                const Float *: MISRA_PRIV_FloatAddConstFloat,                                                              \
                Int: MISRA_PRIV_FloatAddValueInt,                                                                          \
                Float: MISRA_PRIV_FloatAddValueFloat,                                                                      \
                Float *: FloatAdd,                                                                                         \
                const Float *: MISRA_PRIV_FloatAddConstFloat,                                                              \
                Int: MISRA_PRIV_FloatAddValueInt,                                                                          \
                Int *: MISRA_PRIV_FloatAddInt,                                                                             \
            _Generic(                                                                                                      \
                (rhs),                                                                                                     \
                Float: MISRA_PRIV_FloatSubValueFloat,                                                                      \
                Float *: FloatSub,                                                                                         \
                const Float *: MISRA_PRIV_FloatSubConstFloat,                                                              \
                (rhs),                                                                                                     \
                Float: MISRA_PRIV_FloatSubValueFloat,                                                                      \
                Float *: FloatSub,                                                                                         \
                const Float *: MISRA_PRIV_FloatSubConstFloat,                                                              \
                Int: MISRA_PRIV_FloatSubValueInt,                                                                          \
                Float: MISRA_PRIV_FloatSubValueFloat,                                                                      \
                Float *: FloatSub,                                                                                         \
                const Float *: MISRA_PRIV_FloatSubConstFloat,                                                              \
                Int: MISRA_PRIV_FloatSubValueInt,                                                                          \
                Int *: MISRA_PRIV_FloatSubInt,                                                                             \
            _Generic(                                                                                                      \
                (rhs),                                                                                                     \
                Float: MISRA_PRIV_FloatMulValueFloat,                                                                      \
                Float *: FloatMul,                                                                                         \
                const Float *: MISRA_PRIV_FloatMulConstFloat,                                                              \
                (rhs),                                                                                                     \
                Float: MISRA_PRIV_FloatMulValueFloat,                                                                      \
                Float *: FloatMul,                                                                                         \
                const Float *: MISRA_PRIV_FloatMulConstFloat,                                                              \
                Int: MISRA_PRIV_FloatMulValueInt,                                                                          \
                Float: MISRA_PRIV_FloatMulValueFloat,                                                                      \
                Float *: FloatMul,                                                                                         \
                const Float *: MISRA_PRIV_FloatMulConstFloat,                                                              \
                Int: MISRA_PRIV_FloatMulValueInt,                                                                          \
                Int *: MISRA_PRIV_FloatMulInt,                                                                             \
            _Generic(                                                                                                      \
                (rhs),                                                                                                     \
                Float: MISRA_PRIV_FloatDivValueFloat,                                                                      \
                Float *: FloatDiv,                                                                                         \
                const Float *: MISRA_PRIV_FloatDivConstFloat,                                                              \
                (rhs),                                                                                                     \
                Float: MISRA_PRIV_FloatDivValueFloat,                                                                      \
                Float *: FloatDiv,                                                                                         \
                const Float *: MISRA_PRIV_FloatDivConstFloat,                                                              \
                Int: MISRA_PRIV_FloatDivValueInt,                                                                          \
                Float: MISRA_PRIV_FloatDivValueFloat,                                                                      \
                Float *: FloatDiv,                                                                                         \
                const Float *: MISRA_PRIV_FloatDivConstFloat,                                                              \
                Int: MISRA_PRIV_FloatDivValueInt,                                                                          \
                Int *: MISRA_PRIV_FloatDivInt,                                                                             \
    /// TAGS: Float, Convert, Int, Export
    ///
    bool  FloatToInt(Int *result, Float *value);
    ///
    /// Parse a decimal string into a float.
    /// TAGS: Float, Convert, String, Parse
    ///
    Float FloatFromStr(const char *text);
    ///
    /// Convert a float to a normalized decimal string.
    /// TAGS: Float, Convert, String, Format
    ///
    Str   FloatToStr(Float *value);
    
    #ifdef __cplusplus
    /// TAGS: Float, Compare, Ordering
    ///
    int (FloatCompare)(Float *lhs, Float *rhs);
    #ifndef __cplusplus
    #    define MISRA_FLOAT_COMPARE_DISPATCH(rhs)                                                                          \
            _Generic(                                                                                                      \
                (rhs),                                                                                                     \
                Float: MISRA_PRIV_FloatCompareValueFloat,                                                                  \
                Float *: FloatCompare,                                                                                     \
                const Float *: MISRA_PRIV_FloatCompareConstFloat,                                                          \
                (rhs),                                                                                                     \
                Float: MISRA_PRIV_FloatCompareValueFloat,                                                                  \
                Float *: FloatCompare,                                                                                     \
                const Float *: MISRA_PRIV_FloatCompareConstFloat,                                                          \
                Int: MISRA_PRIV_FloatCompareValueInt,                                                                      \
                Float: MISRA_PRIV_FloatCompareValueFloat,                                                                  \
                Float *: FloatCompare,                                                                                     \
                const Float *: MISRA_PRIV_FloatCompareConstFloat,                                                          \
                Int: MISRA_PRIV_FloatCompareValueInt,                                                                      \
                Int *: MISRA_PRIV_FloatCompareInt,                                                                         \
    /// TAGS: Float, Init, Zero, Construct
    ///
    static inline Float FloatInit(void) {
        Float value;
    ///
    static inline Float FloatInit(void) {
        Float value;
    
        value.negative    = false;
    /// TAGS: Float, Deinit, Destroy, Memory
    ///
    static inline void FloatDeinit(Float *value) {
        ValidateFloat(value);
        IntDeinit(&value->significand);
    /// TAGS: Float, Clear, Zero, Reset
    ///
    static inline void FloatClear(Float *value) {
        ValidateFloat(value);
        IntClear(&value->significand);
    /// TAGS: Float, Memory, Clone, Copy
    ///
    Float FloatClone(Float *value);
    
    #ifdef __cplusplus
    /// TAGS: Float, Access, Zero, Predicate
    ///
    bool FloatIsZero(Float *value);
    ///
    /// Test whether a floating-point value is negative.
    /// TAGS: Float, Access, Negative, Predicate
    ///
    bool FloatIsNegative(Float *value);
    ///
    /// Read the base-10 exponent of a float.
    /// TAGS: Float, Access, Exponent
    ///
    i64  FloatExponent(Float *value);
    
    #ifdef __cplusplus
        Int  significand;
        i64  exponent;
    } Float;
    
    ///
    /// TAGS: Float, Validate, Safety, Debug
    ///
    static inline void ValidateFloat(const Float *value) {
        ValidateInt(value ? &value->significand : NULL);
    }
Last updated on