浮点数的二进制乘法如何用C表示?

时间:2016-01-02 05:56:20

标签: c multiplication bits

带有int的二进制乘法算法可以表示如下:

unsigned int multiply(unsigned int multiplier, unsigned int multiplicand) {
    unsigned int product = 0;
    while (multiplier != 0) {
        if ((multiplier & 1) != 0) {
            product = product + multiplicand;
        }
        multiplier = multiplier >> 1;
        multiplicand = multiplicand << 1;
    }
    return product;
}

此函数在没有运算符&#34; *&#34;的情况下执行两个无符号整数的乘法运算。 但它不适用于浮点数,因为浮点数由三部分组成:

IEEE 754 single-precision binary floating-point format

这些部分可以按如下方式隔离:

#include <stdio.h>
typedef union {
    float f;
    struct {
        unsigned int mantisa : 23;
        unsigned int exponent : 8;
        unsigned int sign : 1;
    } parts;
} float_cast;

int main() {
    float_cast d1;
    d1.f = 0.15625;
    printf("sign = %x\n",d1.parts.sign);
    printf("exponent = %x\n",d1.parts.exponent);
    printf("mantisa = %x\n",d1.parts.mantisa);
    return 0;
}

将零件分隔为整数,我可以操作这些钻头。但是如何创建一个函数来乘以浮点的各个部分?

提前致谢

2 个答案:

答案 0 :(得分:3)

  1. 将尾数乘以整数。
  2. 添加指数
  3. Xor the signs。
  4. 有一些细节。

    1. 尾数应该被标准化,这意味着高位为1或尾数为0.为了完全符合,你需要处理变形和其他特殊情况 - 无穷大,NaN,零 - - 您可能需要规范化,变形或溢出(设置为无穷大)。

    2. 产品在[1,4]范围内,假设值为[1,2]。如果尾数的乘积大于2,则需要一些修正:将指数递增1;把mantissas换成一个。

    3. 指数通常与偏移量一起存储。假设指数的实数值是e + m,其中m是常数偏移量。 m需要从两个指数的表示之和中减去,以得到产品的指数。

答案 1 :(得分:0)

这是我的解决方案和答案:

#include <stdio.h>

float multiplyfloat(float multiplier, float multiplicand) {
    typedef union {
        float f;
        unsigned int i;
        struct {
            unsigned int mantissa : 23;
            unsigned int exponent : 8;
            unsigned int sign : 1;
        } parts;
        struct {
            unsigned int mantissa : 23;
            unsigned int b23 : 1;
            unsigned int b31_24 : 8;
        } parts2;
    } float_cast;

    float_cast product, f1, f2, m1, m2;
    product.f = 0.f;
    f1.f = multiplier;
    f2.f = multiplicand;
    m1 = f1;
    m2 = f2;
    m1.parts2.b23 = m2.parts2.b23 = 1;
    m1.parts2.b31_24 = m2.parts2.b31_24 = 0;
    while (m1.parts.mantissa) {
        if (m1.parts2.b23) {
            product.i += m2.i;
        }
        m2.i >>= 1;
        m1.i <<= 1;
    }
    if (product.parts.exponent > 1) {
        product.parts.mantissa >>= product.parts.exponent - 1;
    }
    product.parts.exponent += f1.parts.exponent + f2.parts.exponent - 128;
    product.parts.sign = f1.parts.sign != f2.parts.sign;
    return product.f;
}

int main() {
    float a = 134.337368;
    float b = 151.23000000001;
    float res = multiplyfloat(a, b);
    printf("result  = %f\n", res);
    printf("compare = %f\n", a * b);
    system("pause");
    return 1;
}

有任何问题,请在下面发表评论。感谢