You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无浮点指令实现float加法的精度异常问题求助

无浮点指令的浮点数加法实现问题

我需要实现一个不使用浮点指令的浮点数加法函数,尽量用底层操作方便转汇编。目前函数对1.5+2.5、1.5+-1.5、13.6+52.1这类数值计算正确,但计算1000000+0.0001时得到1.4295e+06的错误结果,而1000000+0能得到正确的1e+06,推测是浮点数精度问题。

相关代码如下:

#include <iostream>

union FloatBits {
    float f;
    uint32_t bits;
};

float add_floats(float a, float b) {
    FloatBits a_bits, b_bits;
    a_bits.f = a; // Initialize the 32 bit value
    b_bits.f = b;
    
    uint32_t a_sign = a_bits.bits & 0x80000000; // Sign 
    a_sign = a_sign >> 31;
    uint32_t a_exponent = a_bits.bits & 0x7f800000; // Exponent
    a_exponent = a_exponent >> 23;
    uint32_t a_mantissa = a_bits.bits & 0x7fffff; // Mantissa

    uint32_t b_sign = b_bits.bits & 0x80000000; // Sign 
    b_sign = b_sign >> 31;
    uint32_t b_exponent = b_bits.bits & 0x7f800000; // Exponent
    b_exponent = b_exponent >> 23;
    uint32_t b_mantissa = b_bits.bits & 0x7fffff; // Mantissa

    std::cout << a_sign << "|" << a_exponent << "|" << a_mantissa << std::endl;
    std::cout << b_sign << "|" << b_exponent << "|" << b_mantissa << std::endl;

    if (a == 0 && b == 0) { 
        return 0.0;
    } else if (a == 0) {
        return b;
    } else if (b == 0) {
        return a;
    }

    // Add the implicit 1's
    a_mantissa |= 0x00800000;
    b_mantissa |= 0x00800000;

    // Normalize
    if (a_exponent < b_exponent) {
        a_mantissa = a_mantissa >> (b_exponent - a_exponent);
        a_exponent = b_exponent;
    } else if (b_exponent < a_exponent) {
        b_mantissa = b_mantissa >> (a_exponent - b_exponent);
        b_exponent = a_exponent;
    } // Else the exponents are equal.  

    uint32_t sign;
    uint32_t exponent = a_exponent; // the exponents are the same due to normalization
    uint32_t mantissa;
    // Add the mantissas
    if (a_sign == b_sign) {
        sign = a_sign;
        mantissa = a_mantissa + b_mantissa;
    } else {
        if (a_mantissa > b_mantissa) {
            sign = a_sign;
            mantissa = a_mantissa - b_mantissa;
        } else if (b_mantissa > a_mantissa){
            sign = b_sign;
            mantissa = b_mantissa - a_mantissa;
        } else if (a_mantissa == b_mantissa) {
            sign = 0;
            exponent = 0;
            mantissa = 0;
        }
    }

    // Handle mantissa overflow
    if (mantissa >= 0x01000000) {
        mantissa >>= 1;
        exponent++;
    }
    std::cout << "-------------------------------------------------------" << std::endl;
    std::cout << sign << "|" << exponent << "|" << mantissa << std::endl;

    FloatBits result;
    result.bits = (sign << 31) | (exponent << 23) | (mantissa & 0x007fffff);
    // std::cout << a << " + " << b << " = " << result.f << std::endl; 
    return result.f;
}

int main() {
    float num1, num2;
    std::cout << "Enter two numbers: ";
    std::cin >> num1 >> num2;
    float test = add_floats(num1, num2);
    std::cout << test;
    return 0;
}

除效率外,代码对多数数值有效,但上述异常情况存在问题。已确认指数归一化逻辑正确,但不确定尾数溢出处理是否恰当,希望得到相关建议。


编辑:发现自己违反了‘不使用浮点指令’的规则,会进行修正,感谢提醒。

更新:已直接改用汇编实现,认为汇编比这种方式更简便。


内容的提问来源于stack exchange,提问作者osy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 21:29:52