Skip to content

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)
    #endif
    #if FEATURE_FLOAT
    #    include <Misra/Std/Container/Float.h>
    #endif
    }
    
    bool float_try_to_decimal_str(Str *out, Float *value, u32 precision, bool has_precision, Allocator *alloc) {
        Str canonical;
        Str result;
    bool float_try_to_scientific_str(
        Str       *out,
        Float     *value,
        u32        precision,
        bool       has_precision,
    
    #if FEATURE_FLOAT
    bool _write_Float(Str *o, FmtInfo *fmt_info, Float *value) {
        size start_len = 0;
        Str  temp;
    
        if (float_fmt_uses_unsupported_flags(fmt_info)) {
            LOG_FATAL("Float only supports decimal and scientific formatting");
        }
    
    #if FEATURE_FLOAT
    Zstr _read_Float(Zstr i, FmtInfo *fmt_info, Float *value) {
        size  token_len = 0;
        Zstr  start     = NULL;
        Zstr  start     = NULL;
        Str   temp;
        Float parsed;
    
        if (!i || !value) {
    
        if (float_fmt_uses_unsupported_flags(fmt_info)) {
            LOG_ERROR("Float only supports decimal and scientific reading");
            StrDeinit(&temp);
            FloatDeinit(&parsed);
    
        if (!StrIterRemainingLength(&si)) {
            LOG_ERROR("Failed to parse Float: empty input");
            StrDeinit(&temp);
            FloatDeinit(&parsed);
    
        if (token_len == 0) {
            LOG_ERROR("Failed to parse Float");
            StrDeinit(&temp);
            FloatDeinit(&parsed);
    /// Arbitrary-precision decimal floating-point implementation built on top of Int.
    
    #include <Misra/Std/Container/Float.h>
    #include <Misra/Std/Zstr.h>
    #include <Misra/Std/Container/Float/Private.h>
    #include <Misra/Std/Container/Float.h>
    #include <Misra/Std/Zstr.h>
    #include <Misra/Std/Container/Float/Private.h>
    #include <Misra/Std/Container/Int.h>
    #include <Misra/Std/Log.h>
    
    
    static void float_normalize(Float *value);
    static void float_replace(Float *dst, Float *src);
    static bool float_try_from_u64_value(Float *out, u64 value, Allocator *alloc);
    
    static void float_normalize(Float *value);
    static void float_replace(Float *dst, Float *src);
    static bool float_try_from_u64_value(Float *out, u64 value, Allocator *alloc);
    static bool float_try_from_i64_value(Float *out, i64 value, Allocator *alloc);
    static void float_normalize(Float *value);
    static void float_replace(Float *dst, Float *src);
    static bool float_try_from_u64_value(Float *out, u64 value, Allocator *alloc);
    static bool float_try_from_i64_value(Float *out, i64 value, Allocator *alloc);
    static bool float_try_from_int_value(Float *out, const Int *value);
    static void float_replace(Float *dst, Float *src);
    static bool float_try_from_u64_value(Float *out, u64 value, Allocator *alloc);
    static bool float_try_from_i64_value(Float *out, i64 value, Allocator *alloc);
    static bool float_try_from_int_value(Float *out, const Int *value);
    static bool float_try_from_f32_value(Float *out, float value, Allocator *alloc);
    static bool float_try_from_u64_value(Float *out, u64 value, Allocator *alloc);
    static bool float_try_from_i64_value(Float *out, i64 value, Allocator *alloc);
    static bool float_try_from_int_value(Float *out, const Int *value);
    static bool float_try_from_f32_value(Float *out, float value, Allocator *alloc);
    static bool float_try_from_f64_value(Float *out, double value, Allocator *alloc);
    static bool float_try_from_i64_value(Float *out, i64 value, Allocator *alloc);
    static bool float_try_from_int_value(Float *out, const Int *value);
    static bool float_try_from_f32_value(Float *out, float value, Allocator *alloc);
    static bool float_try_from_f64_value(Float *out, double value, Allocator *alloc);
    static bool float_pow10(Int *out, u64 power, Allocator *alloc);
    static bool float_try_from_int_value(Float *out, const Int *value);
    static bool float_try_from_f32_value(Float *out, float value, Allocator *alloc);
    static bool float_try_from_f64_value(Float *out, double value, Allocator *alloc);
    static bool float_pow10(Int *out, u64 power, Allocator *alloc);
    static bool float_scale_to_exponent(Float *value, i64 target_exponent);
    static bool float_try_from_f64_value(Float *out, double value, Allocator *alloc);
    static bool float_pow10(Int *out, u64 power, Allocator *alloc);
    static bool float_scale_to_exponent(Float *value, i64 target_exponent);
    static bool float_try_abs_compare(int *out, const Float *lhs, const Float *rhs);
    static i64  float_add_i64_checked(i64 a, i64 b);
    static bool float_pow10(Int *out, u64 power, Allocator *alloc);
    static bool float_scale_to_exponent(Float *value, i64 target_exponent);
    static bool float_try_abs_compare(int *out, const Float *lhs, const 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) {
        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");
        }
    // is bit-perfect, where a decimal-text round-trip via a shortest-form
    // formatter could lose information.
    static bool float_try_from_ieee_bits(Float *out, u64 mantissa, int binexp, bool negative, Allocator *alloc) {
        if (!out) {
            LOG_FATAL("Invalid arguments");
    }
    
    static bool float_try_from_f32_value(Float *out, float value, Allocator *alloc) {
        if (!out) {
            LOG_FATAL("Invalid arguments");
        u32  m    = bits & 0x7FFFFFu;
        if (e == 0xFFu) {
            LOG_FATAL("Float from f32 does not represent finite values (Inf/NaN)");
        }
        u64 mantissa;
    }
    
    static bool float_try_from_f64_value(Float *out, double value, Allocator *alloc) {
        if (!out) {
            LOG_FATAL("Invalid arguments");
        u64  m    = bits & 0xFFFFFFFFFFFFFull;
        if (e == 0x7FFull) {
            LOG_FATAL("Float from f64 does not represent finite values (Inf/NaN)");
        }
        u64 mantissa;
    }
    
    static void float_replace(Float *dst, Float *src) {
        FloatDeinit(dst);
        *dst = *src;
    }
    
    static bool float_scale_to_exponent(Float *value, i64 target_exponent) {
        ValidateFloat(value);
    }
    
    static bool float_try_abs_compare(int *out, const Float *lhs, const Float *rhs) {
        ValidateFloat(lhs);
        ValidateFloat(rhs);
        {
            i64   target_exponent = lhs->exponent < rhs->exponent ? lhs->exponent : rhs->exponent;
            Float lhs_scaled      = FloatInit(FloatAllocator(lhs));
            Float rhs_scaled      = FloatInit(FloatAllocator(rhs));
            i64   target_exponent = lhs->exponent < rhs->exponent ? lhs->exponent : rhs->exponent;
            Float lhs_scaled      = FloatInit(FloatAllocator(lhs));
            Float rhs_scaled      = FloatInit(FloatAllocator(rhs));
    
            if (!FloatTryClone(&lhs_scaled, lhs) || !FloatTryClone(&rhs_scaled, rhs) ||
    }
    
    static void float_normalize(Float *value) {
        ValidateFloat(value);
    }
    
    bool FloatIsZero(const Float *value) {
        ValidateFloat(value);
        return IntIsZero(&value->significand);
    }
    
    bool FloatIsNegative(const Float *value) {
        ValidateFloat(value);
        return !FloatIsZero(value) && value->negative;
    }
    
    i64 FloatExponent(const Float *value) {
        ValidateFloat(value);
        return value->exponent;
    }
    
    Float FloatClone(const Float *value) {
        Float clone;
    
    Float FloatClone(const Float *value) {
        Float clone;
    
        ValidateFloat(value);
    }
    
    bool FloatTryClone(Float *out, const Float *value) {
        if (!out || !value) {
            LOG_FATAL("Invalid arguments");
    }
    
    static bool float_try_from_u64_value(Float *out, u64 value, Allocator *alloc) {
        if (!out) {
            LOG_FATAL("Invalid arguments");
    }
    
    static bool float_try_from_i64_value(Float *out, i64 value, Allocator *alloc) {
        u64 magnitude = 0;
    }
    
    static bool float_try_from_int_value(Float *out, const Int *value) {
        if (!out || !value) {
            LOG_FATAL("Invalid arguments");
    }
    
    Float float_from_u64(u64 value, Allocator *alloc) {
        Float result;
    
    Float float_from_u64(u64 value, Allocator *alloc) {
        Float result;
    
        result = FloatInit(alloc);
    }
    
    Float float_from_i64(i64 value, Allocator *alloc) {
        Float result = FloatInit(alloc);
    
    Float float_from_i64(i64 value, Allocator *alloc) {
        Float result = FloatInit(alloc);
    
        (void)float_try_from_i64_value(&result, value, alloc);
    }
    
    Float float_from_int(const Int *value, Allocator *alloc) {
        Float result;
    
    Float float_from_int(const Int *value, Allocator *alloc) {
        Float result;
    
        ValidateInt(value);
    }
    
    Float float_from_f32(float value, Allocator *alloc) {
        Float result = FloatInit(alloc);
    
    Float float_from_f32(float value, Allocator *alloc) {
        Float result = FloatInit(alloc);
    
        (void)float_try_from_f32_value(&result, value, alloc);
    }
    
    Float float_from_f64(double value, Allocator *alloc) {
        Float result = FloatInit(alloc);
    
    Float float_from_f64(double value, Allocator *alloc) {
        Float result = FloatInit(alloc);
    
        (void)float_try_from_f64_value(&result, value, alloc);
    }
    
    bool FloatToInt(Int *result, const Float *value) {
        ValidateInt(result);
        ValidateFloat(value);
    }
    
    static bool float_try_from_str_impl(Float *out, Zstr text, size length) {
        Float result;
        Str   digits;
    
    static bool float_try_from_str_impl(Float *out, Zstr text, size length) {
        Float result;
        Str   digits;
        size  pos          = 0;
                if (saw_decimal) {
                    if (fractional == INT64_MAX) {
                        LOG_ERROR("Float fractional exponent overflow");
                        goto fail;
                    }
            if (ch == '.') {
                if (saw_decimal) {
                    LOG_ERROR("Invalid Float format");
                    goto fail;
                }
                pos++;
                if (pos >= length) {
                    LOG_ERROR("Invalid Float exponent");
                    goto fail;
                }
                parsed    = ZstrToI64(exp_start, &endptr);
                if (endptr == exp_start) {
                    LOG_ERROR("Invalid Float exponent");
                    goto fail;
                }
                exp_offset = (size)(endptr - text);
                if (exp_offset != length) {
                    LOG_ERROR("Invalid Float exponent");
                    goto fail;
                }
            }
    
            LOG_ERROR("Invalid Float format");
            goto fail;
        }
    
        if (!saw_digit) {
            LOG_ERROR("Invalid Float format");
            goto fail;
        }
    
        if (explicit_exp < INT64_MIN + fractional) {
            LOG_ERROR("Float exponent overflow");
            goto fail;
        }
    }
    
    bool float_try_from_str_zstr(Float *out, Zstr text) {
        if (!out || !text) {
            LOG_FATAL("Invalid arguments");
    }
    
    bool float_try_from_str_str(Float *out, const Str *text) {
        if (!out || !text) {
            LOG_FATAL("Invalid arguments");
    }
    
    Float float_from_str_zstr(Zstr text, Allocator *alloc) {
        Float result = FloatInit(alloc);
    
    Float float_from_str_zstr(Zstr text, Allocator *alloc) {
        Float result = FloatInit(alloc);
    
        (void)float_try_from_str_zstr(&result, text);
    }
    
    Float float_from_str_str(const Str *text, Allocator *alloc) {
        Float result = FloatInit(alloc);
    
    Float float_from_str_str(const Str *text, Allocator *alloc) {
        Float result = FloatInit(alloc);
    
        (void)float_try_from_str_str(&result, text);
    }
    
    bool float_try_to_str(Str *out, const Float *value, Allocator *alloc) {
        Str digits;
        Str result;
    }
    
    Str float_to_str(const Float *value, Allocator *alloc) {
        Str result;
    }
    
    int float_compare_with_error(const Float *lhs, const Float *rhs, bool *error) {
        int cmp = 0;
    
    i32 float_compare(const void *lhs, const void *rhs) {
        return float_compare_with_error((const Float *)lhs, (const Float *)rhs, NULL);
    }
    // inside the Int namespace.
    u64 float_hash(const void *data, u32 size) {
        const Float *value = (const Float *)data;
    
        (void)size;
    }
    
    int float_compare_int_with_error(const Float *lhs, const Int *rhs, bool *error) {
        Float rhs_value = FloatInit(FloatAllocator(lhs));
        int   cmp       = 0;
    
    int float_compare_int_with_error(const Float *lhs, const Int *rhs, bool *error) {
        Float rhs_value = FloatInit(FloatAllocator(lhs));
        int   cmp       = 0;
    }
    
    int float_compare_int(const Float *lhs, const Int *rhs) {
        return float_compare_int_with_error(lhs, rhs, NULL);
    }
    }
    
    int float_compare_u64_with_error(const Float *lhs, u64 rhs, bool *error) {
        Float rhs_value = FloatInit(FloatAllocator(lhs));
        int   cmp       = 0;
    
    int float_compare_u64_with_error(const Float *lhs, u64 rhs, bool *error) {
        Float rhs_value = FloatInit(FloatAllocator(lhs));
        int   cmp       = 0;
    }
    
    int float_compare_u64(const Float *lhs, u64 rhs) {
        return float_compare_u64_with_error(lhs, rhs, NULL);
    }
    }
    
    int float_compare_i64_with_error(const Float *lhs, i64 rhs, bool *error) {
        Float rhs_value = FloatInit(FloatAllocator(lhs));
        int   cmp       = 0;
    
    int float_compare_i64_with_error(const Float *lhs, i64 rhs, bool *error) {
        Float rhs_value = FloatInit(FloatAllocator(lhs));
        int   cmp       = 0;
    }
    
    int float_compare_i64(const Float *lhs, i64 rhs) {
        return float_compare_i64_with_error(lhs, rhs, NULL);
    }
    }
    
    int float_compare_f32_with_error(const Float *lhs, float rhs, bool *error) {
        Float rhs_value = FloatInit(FloatAllocator(lhs));
        int   cmp       = 0;
    
    int float_compare_f32_with_error(const Float *lhs, float rhs, bool *error) {
        Float rhs_value = FloatInit(FloatAllocator(lhs));
        int   cmp       = 0;
    }
    
    int float_compare_f32(const Float *lhs, float rhs) {
        return float_compare_f32_with_error(lhs, rhs, NULL);
    }
    }
    
    int float_compare_f64_with_error(const Float *lhs, double rhs, bool *error) {
        Float rhs_value = FloatInit(FloatAllocator(lhs));
        int   cmp       = 0;
    
    int float_compare_f64_with_error(const Float *lhs, double rhs, bool *error) {
        Float rhs_value = FloatInit(FloatAllocator(lhs));
        int   cmp       = 0;
    }
    
    int float_compare_f64(const Float *lhs, double rhs) {
        return float_compare_f64_with_error(lhs, rhs, NULL);
    }
    }
    
    void FloatNegate(Float *value) {
        ValidateFloat(value);
    }
    
    void FloatAbs(Float *value) {
        ValidateFloat(value);
        value->negative = false;
    }
    
    bool float_add(Float *result, const Float *a, const Float *b) {
        Float lhs;
        Float rhs;
    
    bool float_add(Float *result, const Float *a, const Float *b) {
        Float lhs;
        Float rhs;
        Float temp;
    bool float_add(Float *result, const Float *a, const Float *b) {
        Float lhs;
        Float rhs;
        Float temp;
        i64   exp = 0;
        Float lhs;
        Float rhs;
        Float temp;
        i64   exp = 0;
    }
    
    bool float_add_int(Float *result, const Float *a, const Int *b) {
        Float rhs = FloatInit(FloatAllocator(result));
    
    bool float_add_int(Float *result, const Float *a, const Int *b) {
        Float rhs = FloatInit(FloatAllocator(result));
    
        if (!float_try_from_int_value(&rhs, b)) {
    }
    
    bool float_add_u64(Float *result, const Float *a, u64 b) {
        Float rhs = FloatInit(FloatAllocator(result));
    
    bool float_add_u64(Float *result, const Float *a, u64 b) {
        Float rhs = FloatInit(FloatAllocator(result));
    
        if (!float_try_from_u64_value(&rhs, b, FloatAllocator(result))) {
    }
    
    bool float_add_i64(Float *result, const Float *a, i64 b) {
        Float rhs = FloatInit(FloatAllocator(result));
    
    bool float_add_i64(Float *result, const Float *a, i64 b) {
        Float rhs = FloatInit(FloatAllocator(result));
    
        if (!float_try_from_i64_value(&rhs, b, FloatAllocator(result))) {
    }
    
    bool float_add_f32(Float *result, const Float *a, float b) {
        Float rhs = FloatInit(FloatAllocator(result));
    
    bool float_add_f32(Float *result, const Float *a, float b) {
        Float rhs = FloatInit(FloatAllocator(result));
    
        if (!float_try_from_f32_value(&rhs, b, FloatAllocator(result))) {
    }
    
    bool float_add_f64(Float *result, const Float *a, double b) {
        Float rhs = FloatInit(FloatAllocator(result));
    
    bool float_add_f64(Float *result, const Float *a, double b) {
        Float rhs = FloatInit(FloatAllocator(result));
    
        if (!float_try_from_f64_value(&rhs, b, FloatAllocator(result))) {
    }
    
    bool float_sub(Float *result, const Float *a, const Float *b) {
        Float rhs = FloatInit(FloatAllocator(b));
    
    bool float_sub(Float *result, const Float *a, const Float *b) {
        Float rhs = FloatInit(FloatAllocator(b));
    
        ValidateFloat(result);
    }
    
    bool float_sub_int(Float *result, const Float *a, const Int *b) {
        Float rhs = FloatInit(FloatAllocator(result));
    
    bool float_sub_int(Float *result, const Float *a, const Int *b) {
        Float rhs = FloatInit(FloatAllocator(result));
    
        if (!float_try_from_int_value(&rhs, b)) {
    }
    
    bool float_sub_u64(Float *result, const Float *a, u64 b) {
        Float rhs = FloatInit(FloatAllocator(result));
    
    bool float_sub_u64(Float *result, const Float *a, u64 b) {
        Float rhs = FloatInit(FloatAllocator(result));
    
        if (!float_try_from_u64_value(&rhs, b, FloatAllocator(result))) {
    }
    
    bool float_sub_i64(Float *result, const Float *a, i64 b) {
        Float rhs = FloatInit(FloatAllocator(result));
    
    bool float_sub_i64(Float *result, const Float *a, i64 b) {
        Float rhs = FloatInit(FloatAllocator(result));
    
        if (!float_try_from_i64_value(&rhs, b, FloatAllocator(result))) {
    }
    
    bool float_sub_f32(Float *result, const Float *a, float b) {
        Float rhs = FloatInit(FloatAllocator(result));
    
    bool float_sub_f32(Float *result, const Float *a, float b) {
        Float rhs = FloatInit(FloatAllocator(result));
    
        if (!float_try_from_f32_value(&rhs, b, FloatAllocator(result))) {
    }
    
    bool float_sub_f64(Float *result, const Float *a, double b) {
        Float rhs = FloatInit(FloatAllocator(result));
    
    bool float_sub_f64(Float *result, const Float *a, double b) {
        Float rhs = FloatInit(FloatAllocator(result));
    
        if (!float_try_from_f64_value(&rhs, b, FloatAllocator(result))) {
    }
    
    bool float_mul(Float *result, const Float *a, const Float *b) {
        Float temp = FloatInit(FloatAllocator(result));
    
    bool float_mul(Float *result, const Float *a, const Float *b) {
        Float temp = FloatInit(FloatAllocator(result));
    
        ValidateFloat(result);
    }
    
    bool float_mul_int(Float *result, const Float *a, const Int *b) {
        Float rhs = FloatInit(FloatAllocator(result));
    
    bool float_mul_int(Float *result, const Float *a, const Int *b) {
        Float rhs = FloatInit(FloatAllocator(result));
    
        if (!float_try_from_int_value(&rhs, b)) {
    }
    
    bool float_mul_u64(Float *result, const Float *a, u64 b) {
        Float rhs = FloatInit(FloatAllocator(result));
    
    bool float_mul_u64(Float *result, const Float *a, u64 b) {
        Float rhs = FloatInit(FloatAllocator(result));
    
        if (!float_try_from_u64_value(&rhs, b, FloatAllocator(result))) {
    }
    
    bool float_mul_i64(Float *result, const Float *a, i64 b) {
        Float rhs = FloatInit(FloatAllocator(result));
    
    bool float_mul_i64(Float *result, const Float *a, i64 b) {
        Float rhs = FloatInit(FloatAllocator(result));
    
        if (!float_try_from_i64_value(&rhs, b, FloatAllocator(result))) {
    }
    
    bool float_mul_f32(Float *result, const Float *a, float b) {
        Float rhs = FloatInit(FloatAllocator(result));
    
    bool float_mul_f32(Float *result, const Float *a, float b) {
        Float rhs = FloatInit(FloatAllocator(result));
    
        if (!float_try_from_f32_value(&rhs, b, FloatAllocator(result))) {
    }
    
    bool float_mul_f64(Float *result, const Float *a, double b) {
        Float rhs = FloatInit(FloatAllocator(result));
    
    bool float_mul_f64(Float *result, const Float *a, double b) {
        Float rhs = FloatInit(FloatAllocator(result));
    
        if (!float_try_from_f64_value(&rhs, b, FloatAllocator(result))) {
    }
    
    bool float_div(Float *result, const Float *a, const Float *b, u64 precision) {
        Float temp   = FloatInit(FloatAllocator(result));
        Int   scale  = IntInit(FloatAllocator(result));
    
    bool float_div(Float *result, const Float *a, const Float *b, u64 precision) {
        Float temp   = FloatInit(FloatAllocator(result));
        Int   scale  = IntInit(FloatAllocator(result));
        Int   scaled = IntInit(FloatAllocator(result));
        }
        if (FloatIsZero(a)) {
            Float zero = FloatInit(FloatAllocator(result));
    
            FloatDeinit(result);
    }
    
    bool float_div_int(Float *result, const Float *a, const Int *b, u64 precision) {
        Float rhs = FloatInit(FloatAllocator(result));
        bool  ok  = false;
    
    bool float_div_int(Float *result, const Float *a, const Int *b, u64 precision) {
        Float rhs = FloatInit(FloatAllocator(result));
        bool  ok  = false;
    }
    
    bool float_div_u64(Float *result, const Float *a, u64 b, u64 precision) {
        Float rhs = FloatInit(FloatAllocator(result));
        bool  ok  = false;
    
    bool float_div_u64(Float *result, const Float *a, u64 b, u64 precision) {
        Float rhs = FloatInit(FloatAllocator(result));
        bool  ok  = false;
    }
    
    bool float_div_i64(Float *result, const Float *a, i64 b, u64 precision) {
        Float rhs = FloatInit(FloatAllocator(result));
        bool  ok  = false;
    
    bool float_div_i64(Float *result, const Float *a, i64 b, u64 precision) {
        Float rhs = FloatInit(FloatAllocator(result));
        bool  ok  = false;
    }
    
    bool float_div_f32(Float *result, const Float *a, float b, u64 precision) {
        Float rhs = FloatInit(FloatAllocator(result));
        bool  ok  = false;
    
    bool float_div_f32(Float *result, const Float *a, float b, u64 precision) {
        Float rhs = FloatInit(FloatAllocator(result));
        bool  ok  = false;
    }
    
    bool float_div_f64(Float *result, const Float *a, double b, u64 precision) {
        Float rhs = FloatInit(FloatAllocator(result));
        bool  ok  = false;
    
    bool float_div_f64(Float *result, const Float *a, double b, u64 precision) {
        Float rhs = FloatInit(FloatAllocator(result));
        bool  ok  = false;
    #include <Misra/Std/Allocator/Default.h>
    #include <Misra/Std/Container/Float.h>
    #include <Misra/Std/Container/Int.h>
    #include <Misra/Std/Container/Map.h>
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float a = FloatFromStr("1.23", &alloc.base);
        Float b = FloatFromStr("123e-2", &alloc.base);
        Float c = FloatFromStr("-1.23", &alloc.base);
    
        Float a = FloatFromStr("1.23", &alloc.base);
        Float b = FloatFromStr("123e-2", &alloc.base);
        Float c = FloatFromStr("-1.23", &alloc.base);
        Float a = FloatFromStr("1.23", &alloc.base);
        Float b = FloatFromStr("123e-2", &alloc.base);
        Float c = FloatFromStr("-1.23", &alloc.base);
    
        bool result = FloatCompare(&a, &b) == 0;
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float a = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES, &alloc.base);
        Float b = FloatFromStr(FLOAT_TEST_VERY_LARGE_TWOS, &alloc.base);
        Float c = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES, &alloc.base);
    
        Float a = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES, &alloc.base);
        Float b = FloatFromStr(FLOAT_TEST_VERY_LARGE_TWOS, &alloc.base);
        Float c = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES, &alloc.base);
        Float a = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES, &alloc.base);
        Float b = FloatFromStr(FLOAT_TEST_VERY_LARGE_TWOS, &alloc.base);
        Float c = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES, &alloc.base);
    
        bool result = FloatLT(&a, &b);
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float large          = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES, &alloc.base);
        Float negative_large = FloatFromStr("-" FLOAT_TEST_VERY_LARGE_ONES, &alloc.base);
        Float small          = FloatFromStr("2.5", &alloc.base);
    
        Float large          = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES, &alloc.base);
        Float negative_large = FloatFromStr("-" FLOAT_TEST_VERY_LARGE_ONES, &alloc.base);
        Float small          = FloatFromStr("2.5", &alloc.base);
        Float large          = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES, &alloc.base);
        Float negative_large = FloatFromStr("-" FLOAT_TEST_VERY_LARGE_ONES, &alloc.base);
        Float small          = FloatFromStr("2.5", &alloc.base);
    
        bool result = FloatGT(&large, &small);
    
    bool test_float_compare_wrappers(void) {
        WriteFmt("Testing Float compare macros\n");
    
        DefaultAllocator alloc = DefaultAllocatorInit();
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float a        = FloatFromStr("-2", &alloc.base);
        Float b        = FloatFromStr("0.5", &alloc.base);
        Float expected = FloatFromStr("5e-1", &alloc.base);
    
        Float a        = FloatFromStr("-2", &alloc.base);
        Float b        = FloatFromStr("0.5", &alloc.base);
        Float expected = FloatFromStr("5e-1", &alloc.base);
        Float a        = FloatFromStr("-2", &alloc.base);
        Float b        = FloatFromStr("0.5", &alloc.base);
        Float expected = FloatFromStr("5e-1", &alloc.base);
    
        bool result = FloatLT(&a, &b);
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float value = FloatFromStr("12.5", &alloc.base);
        Float same  = FloatFromStr("12.5", &alloc.base);
        Int   whole = IntFrom(12, &alloc.base);
    
        Float value = FloatFromStr("12.5", &alloc.base);
        Float same  = FloatFromStr("12.5", &alloc.base);
        Int   whole = IntFrom(12, &alloc.base);
        Int   next  = IntFrom(13, &alloc.base);
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float a     = FloatFromStr("1.23", &alloc.base);
        Float b     = FloatFromStr("123e-2", &alloc.base);
        Float zero1 = FloatFromStr("0", &alloc.base);
    
        Float a     = FloatFromStr("1.23", &alloc.base);
        Float b     = FloatFromStr("123e-2", &alloc.base);
        Float zero1 = FloatFromStr("0", &alloc.base);
        Float zero2 = FloatFromStr("0", &alloc.base);
        Float a     = FloatFromStr("1.23", &alloc.base);
        Float b     = FloatFromStr("123e-2", &alloc.base);
        Float zero1 = FloatFromStr("0", &alloc.base);
        Float zero2 = FloatFromStr("0", &alloc.base);
        Float b     = FloatFromStr("123e-2", &alloc.base);
        Float zero1 = FloatFromStr("0", &alloc.base);
        Float zero2 = FloatFromStr("0", &alloc.base);
    
        bool result = (float_hash(&a, 0) == float_hash(&b, 0));
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float pos   = FloatFromStr("1.5e3", &alloc.base);
        Float neg   = FloatFromStr("-1.5e3", &alloc.base);
        Float small = FloatFromStr("1.5e2", &alloc.base);
    
        Float pos   = FloatFromStr("1.5e3", &alloc.base);
        Float neg   = FloatFromStr("-1.5e3", &alloc.base);
        Float small = FloatFromStr("1.5e2", &alloc.base);
        Float zero  = FloatFromStr("0", &alloc.base);
        Float pos   = FloatFromStr("1.5e3", &alloc.base);
        Float neg   = FloatFromStr("-1.5e3", &alloc.base);
        Float small = FloatFromStr("1.5e2", &alloc.base);
        Float zero  = FloatFromStr("0", &alloc.base);
        Float one   = FloatFromStr("1", &alloc.base);
        Float neg   = FloatFromStr("-1.5e3", &alloc.base);
        Float small = FloatFromStr("1.5e2", &alloc.base);
        Float zero  = FloatFromStr("0", &alloc.base);
        Float one   = FloatFromStr("1", &alloc.base);
        Float small = FloatFromStr("1.5e2", &alloc.base);
        Float zero  = FloatFromStr("0", &alloc.base);
        Float one   = FloatFromStr("1", &alloc.base);
    
        u64 h_pos   = float_hash(&pos, 0);
    // the GenericHash / GenericCompare-shaped helpers wire in directly.
    bool test_float_hash_as_map_key(void) {
        WriteFmt("Testing float_hash as Map<Float, u64> key\n");
    
        DefaultAllocator alloc = DefaultAllocatorInit();
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Map(Float, u64) counts = MapInit(float_hash, float_compare, &alloc);
    
        Float k1 = FloatFromStr("3.14", &alloc.base);
        Map(Float, u64) counts = MapInit(float_hash, float_compare, &alloc);
    
        Float k1 = FloatFromStr("3.14", &alloc.base);
        Float k2 = FloatFromStr("2.71", &alloc.base);
        MapInsertR(&counts, k1, 1u);
    
        Float k1 = FloatFromStr("3.14", &alloc.base);
        Float k2 = FloatFromStr("2.71", &alloc.base);
        MapInsertR(&counts, k1, 1u);
        MapInsertR(&counts, k2, 2u);
        MapInsertR(&counts, k2, 2u);
    
        Float probe   = FloatFromStr("314e-2", &alloc.base); // same value as k1
        u64  *got     = MapGetFirstPtr(&counts, probe);
        Float missing = FloatFromStr("9.99", &alloc.base);
        Float probe   = FloatFromStr("314e-2", &alloc.base); // same value as k1
        u64  *got     = MapGetFirstPtr(&counts, probe);
        Float missing = FloatFromStr("9.99", &alloc.base);
        u64  *gone    = MapGetFirstPtr(&counts, missing);
    
    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");
    }
    #include <Misra/Std/Container/BitVec.h>
    #include <Misra/Std/Container/Int.h>
    #include <Misra/Std/Container/Float.h>
    #include <Misra/Std/Io.h>
    #include <Misra/Std/Log.h>
    
    bool test_float_reading(void) {
        WriteFmt("Testing Float reading\n");
    
        DefaultAllocator alloc      = DefaultAllocatorInit();
        bool success = true;
    
        Float dec = FloatInit(alloc_base);
        Float sci = FloatInit(alloc_base);
        Float neg = FloatInit(alloc_base);
    
        Float dec = FloatInit(alloc_base);
        Float sci = FloatInit(alloc_base);
        Float neg = FloatInit(alloc_base);
        Float dec = FloatInit(alloc_base);
        Float sci = FloatInit(alloc_base);
        Float neg = FloatInit(alloc_base);
    
        Str dec_text = StrInit(&alloc);
    #include <Misra/Std/Allocator/Default.h>
    #include <Misra/Std/Zstr.h>
    #include <Misra/Std/Container/Float.h>
    #include <Misra/Std/Log.h>
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float value = FloatInit(&alloc.base);
    
        bool result = FloatIsZero(&value);
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float value = FloatFromStr("-123.45", &alloc.base);
    
        FloatClear(&value);
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float original = FloatFromStr("-12.5", &alloc.base);
        Float clone    = FloatClone(&original);
        Float expected = FloatFromStr("-12.5", &alloc.base);
    
        Float original = FloatFromStr("-12.5", &alloc.base);
        Float clone    = FloatClone(&original);
        Float expected = FloatFromStr("-12.5", &alloc.base);
        Str   text     = FloatToStr(&clone);
        Float original = FloatFromStr("-12.5", &alloc.base);
        Float clone    = FloatClone(&original);
        Float expected = FloatFromStr("-12.5", &alloc.base);
        Str   text     = FloatToStr(&clone);
        // a non-trivial three-bit magnitude that exercises the clone-vs-original
        // equality check below.
        Float original = FloatFromStr("-0.005", &alloc.base);
    
        Float clone = FloatClone(&original);
        Float original = FloatFromStr("-0.005", &alloc.base);
    
        Float clone = FloatClone(&original);
    
        bool result = FloatEQ(&clone, &original) && FloatAllocator(&clone) == FloatAllocator(&original) &&
    
    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");
    }
    #include <Misra/Std/Allocator/Default.h>
    #include <Misra/Std/Zstr.h>
    #include <Misra/Std/Container/Float.h>
    #include <Misra/Std/Container/Int.h>
    #include <Misra/Std/Log.h>
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float value = float_from_u64(42, ALLOCATOR_OF(&alloc));
        Str   text  = FloatToStr(&value);
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float value = float_from_i64(-42, ALLOCATOR_OF(&alloc));
        Str   text  = FloatToStr(&value);
    
        Int   integer = IntFromStr("12345678901234567890", ALLOCATOR_OF(&alloc));
        Float value   = float_from_int(&integer, ALLOCATOR_OF(&alloc));
        Str   text    = FloatToStr(&value);
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float value        = FloatFromStr("1234500e-2", ALLOCATOR_OF(&alloc));
        Int   result_value = IntInit(ALLOCATOR_OF(&alloc));
        Str   text         = StrInit(ALLOCATOR_OF(&alloc));
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float value        = FloatFromStr("123.45", ALLOCATOR_OF(&alloc));
        Int   result_value = IntFrom(99, ALLOCATOR_OF(&alloc));
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float value        = FloatFromStr("-42", ALLOCATOR_OF(&alloc));
        Int   result_value = IntFrom(99, ALLOCATOR_OF(&alloc));
    
    bool test_float_string_round_trip(void) {
        WriteFmt("Testing Float string round trip\n");
    
        DefaultAllocator alloc = DefaultAllocatorInit();
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float value = FloatFromStr("-123.45", ALLOCATOR_OF(&alloc));
        Str   text  = FloatToStr(&value);
        alloc.base.retry_limit = 5;
    
        Float value = FloatFromStr("-123.45", ALLOCATOR_OF(&alloc));
    
        ok = float_try_to_str(&text, &value, ALLOCATOR_OF(&alloc));
    
    bool test_float_very_large_string_round_trip(void) {
        WriteFmt("Testing Float very large string round trip\n");
    
        DefaultAllocator alloc = DefaultAllocatorInit();
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float value = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES, ALLOCATOR_OF(&alloc));
        Str   text  = FloatToStr(&value);
    
    bool test_float_scientific_parse(void) {
        WriteFmt("Testing Float scientific parsing\n");
    
        DefaultAllocator alloc = DefaultAllocatorInit();
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float value = FloatFromStr("1.2300e3", ALLOCATOR_OF(&alloc));
        Str   text  = FloatToStr(&value);
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float parsed = FloatFromStr("12.3.4", ALLOCATOR_OF(&alloc));
        Float value  = FloatInit(ALLOCATOR_OF(&alloc));
        bool  result = !FloatTryFromStr(&value, "12.3.4");
    
        Float parsed = FloatFromStr("12.3.4", ALLOCATOR_OF(&alloc));
        Float value  = FloatInit(ALLOCATOR_OF(&alloc));
        bool  result = !FloatTryFromStr(&value, "12.3.4");
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float parsed = FloatFromStr((Zstr)NULL, ALLOCATOR_OF(&alloc));
        Float value  = FloatInit(ALLOCATOR_OF(&alloc));
        bool  result = !FloatTryFromStr(&value, (Zstr)NULL);
    
        Float parsed = FloatFromStr((Zstr)NULL, ALLOCATOR_OF(&alloc));
        Float value  = FloatInit(ALLOCATOR_OF(&alloc));
        bool  result = !FloatTryFromStr(&value, (Zstr)NULL);
    
    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/BitVec.h>
    #include <Misra/Std/Container/Int.h>
    #include <Misra/Std/Container/Float.h>
    #include <Misra/Std/Io.h>
    #include <Misra/Std/Log.h>
    
    bool test_float_formatting(void) {
        WriteFmt("Testing Float formatting\n");
    
        DefaultAllocator alloc      = DefaultAllocatorInit();
        Str   output  = StrInit(&alloc);
        bool  success = true;
        Float exact   = FloatFromStr("1234567890.012345", alloc_base);
        Float sci     = FloatFromStr("12345.67", alloc_base);
        Float short_v = FloatFromStr("1.2", alloc_base);
        bool  success = true;
        Float exact   = FloatFromStr("1234567890.012345", alloc_base);
        Float sci     = FloatFromStr("12345.67", alloc_base);
        Float short_v = FloatFromStr("1.2", alloc_base);
        Float exact   = FloatFromStr("1234567890.012345", alloc_base);
        Float sci     = FloatFromStr("12345.67", alloc_base);
        Float short_v = FloatFromStr("1.2", alloc_base);
    
        StrAppendFmt(&output, "{}", exact);
    #include <Misra/Std/Allocator/Default.h>
    #include <Misra/Std/Zstr.h>
    #include <Misra/Std/Container/Float.h>
    #include <Misra/Std/Container/Int.h>
    #include <Misra/Std/Log.h>
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float value = FloatFromStr("12.5", &alloc.base);
        Str   text  = StrInit(&alloc.base);
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float a            = FloatFromStr("1.2", &alloc.base);
        Float b            = FloatFromStr("0.03", &alloc.base);
        Float result_value = FloatInit(&alloc.base);
    
        Float a            = FloatFromStr("1.2", &alloc.base);
        Float b            = FloatFromStr("0.03", &alloc.base);
        Float result_value = FloatInit(&alloc.base);
        Str   text         = StrInit(&alloc.base);
        Float a            = FloatFromStr("1.2", &alloc.base);
        Float b            = FloatFromStr("0.03", &alloc.base);
        Float result_value = FloatInit(&alloc.base);
        Str   text         = StrInit(&alloc.base);
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float a            = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES, &alloc.base);
        Float b            = FloatFromStr(FLOAT_TEST_VERY_LARGE_TWOS, &alloc.base);
        Float result_value = FloatInit(&alloc.base);
    
        Float a            = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES, &alloc.base);
        Float b            = FloatFromStr(FLOAT_TEST_VERY_LARGE_TWOS, &alloc.base);
        Float result_value = FloatInit(&alloc.base);
        Str   text         = StrInit(&alloc.base);
        Float a            = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES, &alloc.base);
        Float b            = FloatFromStr(FLOAT_TEST_VERY_LARGE_TWOS, &alloc.base);
        Float result_value = FloatInit(&alloc.base);
        Str   text         = StrInit(&alloc.base);
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float a            = FloatFromStr("1.25", &alloc.base);
        Float b            = FloatFromStr("0.75", &alloc.base);
        Int   whole        = IntFrom(2, &alloc.base);
    
        Float a            = FloatFromStr("1.25", &alloc.base);
        Float b            = FloatFromStr("0.75", &alloc.base);
        Int   whole        = IntFrom(2, &alloc.base);
        Float result_value = FloatInit(&alloc.base);
        Float b            = FloatFromStr("0.75", &alloc.base);
        Int   whole        = IntFrom(2, &alloc.base);
        Float result_value = FloatInit(&alloc.base);
        Str   text         = StrInit(&alloc.base);
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float a            = FloatFromStr("1.5", &alloc.base);
        Float b            = FloatFromStr("2", &alloc.base);
        Float result_value = FloatInit(&alloc.base);
    
        Float a            = FloatFromStr("1.5", &alloc.base);
        Float b            = FloatFromStr("2", &alloc.base);
        Float result_value = FloatInit(&alloc.base);
        Str   text         = StrInit(&alloc.base);
        Float a            = FloatFromStr("1.5", &alloc.base);
        Float b            = FloatFromStr("2", &alloc.base);
        Float result_value = FloatInit(&alloc.base);
        Str   text         = StrInit(&alloc.base);
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float a            = FloatFromStr(FLOAT_TEST_VERY_LARGE_THREES, &alloc.base);
        Float b            = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES, &alloc.base);
        Float result_value = FloatInit(&alloc.base);
    
        Float a            = FloatFromStr(FLOAT_TEST_VERY_LARGE_THREES, &alloc.base);
        Float b            = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES, &alloc.base);
        Float result_value = FloatInit(&alloc.base);
        Str   text         = StrInit(&alloc.base);
        Float a            = FloatFromStr(FLOAT_TEST_VERY_LARGE_THREES, &alloc.base);
        Float b            = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES, &alloc.base);
        Float result_value = FloatInit(&alloc.base);
        Str   text         = StrInit(&alloc.base);
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float a            = FloatFromStr("5.5", &alloc.base);
        Float b            = FloatFromStr("0.5", &alloc.base);
        Int   whole        = IntFrom(2, &alloc.base);
    
        Float a            = FloatFromStr("5.5", &alloc.base);
        Float b            = FloatFromStr("0.5", &alloc.base);
        Int   whole        = IntFrom(2, &alloc.base);
        Float result_value = FloatInit(&alloc.base);
        Float b            = FloatFromStr("0.5", &alloc.base);
        Int   whole        = IntFrom(2, &alloc.base);
        Float result_value = FloatInit(&alloc.base);
        Str   text         = StrInit(&alloc.base);
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float a            = FloatFromStr("12.5", &alloc.base);
        Float b            = FloatFromStr("-0.2", &alloc.base);
        Float result_value = FloatInit(&alloc.base);
    
        Float a            = FloatFromStr("12.5", &alloc.base);
        Float b            = FloatFromStr("-0.2", &alloc.base);
        Float result_value = FloatInit(&alloc.base);
        Str   text         = StrInit(&alloc.base);
        Float a            = FloatFromStr("12.5", &alloc.base);
        Float b            = FloatFromStr("-0.2", &alloc.base);
        Float result_value = FloatInit(&alloc.base);
        Str   text         = StrInit(&alloc.base);
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float a            = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES, &alloc.base);
        Float b            = FloatFromStr("2", &alloc.base);
        Float result_value = FloatInit(&alloc.base);
    
        Float a            = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES, &alloc.base);
        Float b            = FloatFromStr("2", &alloc.base);
        Float result_value = FloatInit(&alloc.base);
        Str   text         = StrInit(&alloc.base);
        Float a            = FloatFromStr(FLOAT_TEST_VERY_LARGE_ONES, &alloc.base);
        Float b            = FloatFromStr("2", &alloc.base);
        Float result_value = FloatInit(&alloc.base);
        Str   text         = StrInit(&alloc.base);
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float a            = FloatFromStr("1.5", &alloc.base);
        Float b            = FloatFromStr("2", &alloc.base);
        Int   whole        = IntFrom(2, &alloc.base);
    
        Float a            = FloatFromStr("1.5", &alloc.base);
        Float b            = FloatFromStr("2", &alloc.base);
        Int   whole        = IntFrom(2, &alloc.base);
        Float result_value = FloatInit(&alloc.base);
        Float b            = FloatFromStr("2", &alloc.base);
        Int   whole        = IntFrom(2, &alloc.base);
        Float result_value = FloatInit(&alloc.base);
        Str   text         = StrInit(&alloc.base);
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float a            = FloatFromStr("1", &alloc.base);
        Float b            = FloatFromStr("8", &alloc.base);
        Float result_value = FloatInit(&alloc.base);
    
        Float a            = FloatFromStr("1", &alloc.base);
        Float b            = FloatFromStr("8", &alloc.base);
        Float result_value = FloatInit(&alloc.base);
        Str   text         = StrInit(&alloc.base);
        Float a            = FloatFromStr("1", &alloc.base);
        Float b            = FloatFromStr("8", &alloc.base);
        Float result_value = FloatInit(&alloc.base);
        Str   text         = StrInit(&alloc.base);
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float a            = FloatFromStr(FLOAT_TEST_VERY_LARGE_TWOS, &alloc.base);
        Float b            = FloatFromStr("2", &alloc.base);
        Float result_value = FloatInit(&alloc.base);
    
        Float a            = FloatFromStr(FLOAT_TEST_VERY_LARGE_TWOS, &alloc.base);
        Float b            = FloatFromStr("2", &alloc.base);
        Float result_value = FloatInit(&alloc.base);
        Str   text         = StrInit(&alloc.base);
        Float a            = FloatFromStr(FLOAT_TEST_VERY_LARGE_TWOS, &alloc.base);
        Float b            = FloatFromStr("2", &alloc.base);
        Float result_value = FloatInit(&alloc.base);
        Str   text         = StrInit(&alloc.base);
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float a            = FloatFromStr("7.5", &alloc.base);
        Float b            = FloatFromStr("2.5", &alloc.base);
        Int   whole        = IntFrom(3, &alloc.base);
    
        Float a            = FloatFromStr("7.5", &alloc.base);
        Float b            = FloatFromStr("2.5", &alloc.base);
        Int   whole        = IntFrom(3, &alloc.base);
        Float result_value = FloatInit(&alloc.base);
        Float b            = FloatFromStr("2.5", &alloc.base);
        Int   whole        = IntFrom(3, &alloc.base);
        Float result_value = FloatInit(&alloc.base);
        Str   text         = StrInit(&alloc.base);
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float a = FloatFromStr("1", &alloc.base);
        Float b = FloatInit(&alloc.base);
        Float r = FloatInit(&alloc.base);
    
        Float a = FloatFromStr("1", &alloc.base);
        Float b = FloatInit(&alloc.base);
        Float r = FloatInit(&alloc.base);
        bool  ok;
        Float a = FloatFromStr("1", &alloc.base);
        Float b = FloatInit(&alloc.base);
        Float r = FloatInit(&alloc.base);
        bool  ok;
    
    int main(void) {
        WriteFmt("[INFO] Starting Float.Math tests\n\n");
    
        TestFunction tests[] = {
        int total_deadend_tests = 0;
    
        return run_test_suite(tests, total_tests, deadend_tests, total_deadend_tests, "Float.Math");
    }
    #include <Misra/Std/Allocator/Default.h>
    #include <Misra/Std/Container/Float.h>
    #include <Misra/Std/Log.h>
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float zero  = FloatInit(&alloc.base);
        Float value = FloatFromStr("0.001", &alloc.base);
    
        Float zero  = FloatInit(&alloc.base);
        Float value = FloatFromStr("0.001", &alloc.base);
    
        bool result = FloatIsZero(&zero);
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float neg  = FloatFromStr("-42", &alloc.base);
        Float pos  = FloatFromStr("42", &alloc.base);
        Float zero = FloatFromStr("-0.0", &alloc.base);
    
        Float neg  = FloatFromStr("-42", &alloc.base);
        Float pos  = FloatFromStr("42", &alloc.base);
        Float zero = FloatFromStr("-0.0", &alloc.base);
        Float neg  = FloatFromStr("-42", &alloc.base);
        Float pos  = FloatFromStr("42", &alloc.base);
        Float zero = FloatFromStr("-0.0", &alloc.base);
    
        bool result = FloatIsNegative(&neg);
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Float value = FloatFromStr("12.34", &alloc.base);
    
        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");
    }
    #if FEATURE_FLOAT
    #    define IOFMT_FLOAT_CASE_(x, addr)                                                                                 \
    Float:                                                                                                                 \
            TO_TYPE_SPECIFIC_IO(Float, addr),
    #else
    #    define IOFMT_FLOAT_CASE_(x, addr)                                                                                 \
    Float:                                                                                                                 \
            TO_TYPE_SPECIFIC_IO(Float, addr),
    #else
    #    define IOFMT_FLOAT_CASE_(x, addr)
    /// TAGS: Float, Format, Decimal
    ///
    bool float_try_to_decimal_str(Str *out, Float *value, u32 precision, bool has_precision, Allocator *alloc);
    #    define FloatTryToDecimalStr(...) OVERLOAD(FloatTryToDecimalStr, __VA_ARGS__)
    #    define FloatTryToDecimalStr_4(out, value, precision, has_precision)                                               \
    bool float_try_to_scientific_str(
        Str       *out,
        Float     *value,
        u32        precision,
        bool       has_precision,
    bool _write_f64(Str *o, FmtInfo *fmt_info, f64 *v);
    #if FEATURE_FLOAT
    bool _write_Float(Str *o, FmtInfo *fmt_info, Float *value);
    #endif
    #if FEATURE_BITVEC
    Zstr _read_f64(Zstr i, FmtInfo *fmt_info, f64 *v);
    #if FEATURE_FLOAT
    Zstr _read_Float(Zstr i, FmtInfo *fmt_info, Float *value);
    #endif
    #if FEATURE_BITVEC
    #endif
    #if FEATURE_FLOAT
    #    include <Misra/Std/Container/Float.h>
    #endif
    #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
    ///
    #define FloatInit(...)             OVERLOAD(FloatInit, __VA_ARGS__)
    #define FloatInit_0()              ((Float) {.negative = false, .significand = IntInit_1(MisraScope), .exponent = 0})
    #define FloatInit_1(allocator_ptr) ((Float) {.negative = false, .significand = IntInit_1(allocator_ptr), .exponent = 0})
    #define FloatInit(...)             OVERLOAD(FloatInit, __VA_ARGS__)
    #define FloatInit_0()              ((Float) {.negative = false, .significand = IntInit_1(MisraScope), .exponent = 0})
    #define FloatInit_1(allocator_ptr) ((Float) {.negative = false, .significand = IntInit_1(allocator_ptr), .exponent = 0})
    
    ///
    /// TAGS: Float, Deinit, 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, Access, Zero, Predicate
        ///
        bool FloatIsZero(const Float *value);
        ///
        /// Test whether a floating-point value is negative.
        /// TAGS: Float, Access, Negative, Predicate
        ///
        bool FloatIsNegative(const Float *value);
        ///
        /// Read the base-10 exponent of a float.
        /// TAGS: Float, Access, Exponent
        ///
        i64 FloatExponent(const Float *value);
    
    #ifdef __cplusplus
        /// TAGS: Float, Convert, Int, Truncate
        ///
        bool FloatToInt(Int *result, const Float *value);
    
        ///
        /// TAGS: Float, Convert, Parse, Decimal
        ///
        bool float_try_from_str_zstr(Float *out, Zstr text);
        bool float_try_from_str_str(Float *out, const Str *text);
    #define FloatTryFromStr(out, text)                                                                                     \
        ///
        bool float_try_from_str_zstr(Float *out, Zstr text);
        bool float_try_from_str_str(Float *out, const Str *text);
    #define FloatTryFromStr(out, text)                                                                                     \
        _Generic((text), Str *: float_try_from_str_str, Zstr: float_try_from_str_zstr, char *: float_try_from_str_zstr)(   \
        /// TAGS: Float, Convert, String
        ///
        Float float_from_str_zstr(Zstr text, Allocator *alloc);
        Float float_from_str_str(const Str *text, Allocator *alloc);
    #define FloatFromStr(...) OVERLOAD(FloatFromStr, __VA_ARGS__)
        ///
        Float float_from_str_zstr(Zstr text, Allocator *alloc);
        Float float_from_str_str(const Str *text, Allocator *alloc);
    #define FloatFromStr(...) OVERLOAD(FloatFromStr, __VA_ARGS__)
    #define FloatFromStr_1(text)                                                                                           \
        )
    
        bool float_try_to_str(Str *out, const Float *value, Allocator *alloc);
        Str  float_to_str(const Float *value, Allocator *alloc);
    
        bool float_try_to_str(Str *out, const Float *value, Allocator *alloc);
        Str  float_to_str(const Float *value, Allocator *alloc);
    
    #ifdef __cplusplus
        /// 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
        ///
        bool float_add(Float *result, const Float *a, const Float *b);
        ///
        /// Subtract one float from another.
        /// TAGS: Float, Math, Subtract
        ///
        bool float_sub(Float *result, const Float *a, const Float *b);
        ///
        /// Multiply two floats.
        /// TAGS: Float, Math, Multiply
        ///
        bool float_mul(Float *result, const Float *a, const Float *b);
        ///
        /// Divide one float by another.
        /// TAGS: Float, Math, Divide, Precision
        ///
        bool float_div(Float *result, const Float *a, const Float *b, u64 precision);
    #ifndef __cplusplus
    ///
            _Generic(                                                                                                      \
                (b),                                                                                                       \
                Float *: float_add,                                                                                        \
                Int *: float_add_int,                                                                                      \
                unsigned char: float_add_u64,                                                                              \
            _Generic(                                                                                                      \
                (b),                                                                                                       \
                Float *: float_sub,                                                                                        \
                Int *: float_sub_int,                                                                                      \
                unsigned char: float_sub_u64,                                                                              \
            _Generic(                                                                                                      \
                (b),                                                                                                       \
                Float *: float_mul,                                                                                        \
                Int *: float_mul_int,                                                                                      \
                unsigned char: float_mul_u64,                                                                              \
            _Generic(                                                                                                      \
                (b),                                                                                                       \
                Float *: float_div,                                                                                        \
                Int *: float_div_int,                                                                                      \
                unsigned char: float_div_u64,                                                                              \
        /// TAGS: Float, Memory, Clone, Copy
        ///
        bool FloatTryClone(Float *out, const Float *value);
    
        ///
        /// TAGS: Float, Memory, Clone, Copy
        ///
        Float FloatClone(const 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);
    }
        /// TAGS: Float, Compare, Ordering, GenericCompare
        ///
        int float_compare_with_error(const Float *lhs, const Float *rhs, bool *error);
        i32 float_compare(const void *lhs, const void *rhs);
            _Generic(                                                                                                      \
                (rhs),                                                                                                     \
                Float *: float_compare,                                                                                    \
                Int *: float_compare_int,                                                                                  \
                unsigned char: float_compare_u64,                                                                          \
            _Generic(                                                                                                      \
                (rhs),                                                                                                     \
                Float *: float_compare_with_error,                                                                         \
                Int *: float_compare_int_with_error,                                                                       \
                unsigned char: float_compare_u64_with_error,                                                               \
Last updated on