Násobení čísel typu float

#include <iostream>
#include <cassert>
using namespace std;
 
const int bias = 127;
const int emax = 255;
const int emin = 0;
 
struct Number
{
    unsigned int m : 23;  // 23 bitu                            1 . m1 m2 m3   m23
    unsigned int e :  8;  // exponent 8 bitu, e = 0 ... 255,    2^(e-127)
    unsigned int s :  1;  // znamenko, s = 0 nebo 1,            (-1)^s
};
 
void mul (Number & z, Number x, Number y) // z = x*y
{
    int xm = x.m | 1 << 23;
    int ym = y.m | 1 << 23;
 
    // vysledna mantisa
    int m = 0;
 
    // znamenko
    z.s = x.s ^ y.s; //  1 xor 1 je 1
 
    int e = x.e + y.e - bias;
    if (x.e == emin || y.e == emin)
    {
        z.e = emin; // nula
    }
    elseif (e >= emax)
    {
        z.e = emax; // preteceni
    }
    else if (e <= emin)
    {
        z.e = emin; // zaokrouhlime na nulu
    }
    else
    {
        for (int i = 0; i <= 23; i++)
            for (int k = 0; k <= 23-i; k++)
            {
                int xi = (xm >> (23-i)) & 1; // posuneme doprava a ponechame jeden bit
                int yk = (ym >> (23-k)) & 1;
                int zbit = xi & yk;
 
                int inx = 23 - i - k;
                if (inx >= 0)
                    m += zbit << (23 - i - k); // posuneme doleva
            }
 
        int t = m >> 23;
        if (t >= 2)
        {
            e += 1;
            m >>= 1;
        }
 
        if (e > emax)
        {
            z.e = emax;
        }
        else
        {
            z.e = e;
 
            const int mask = (1 << 23) - 1; // 23 jednicek, 0x7fffff
            m = m & mask; // ponechame 23 dolnich bitu
            // m &= mask;
        }
    }
    z.m = m;
}
 
inline Number floatToNumber (float f)
{
    return  * (Number *) & f;
    // Number* p = (Number*) /* (void*) */ &f;
    // return *p;
}
 
inline float numberToFloat (Number x)
{
    return * (float *) & x;
    // float * p = (float *) /* (void*) */ & x;
    // return *p;
}
 
float mult (float xx, float yy)
{
    Number x = floatToNumber (xx);
    Number y = floatToNumber (yy);
    Number z;
    mul (z, x, y);
    float zz = numberToFloat (z);
    return zz;
}
 
int main()
{
    assert (sizeof (Number) == 4);
    float xx = 10;
    float yy = 0.125;
    float zz = mult (xx, yy);
    float vv = xx;
    vv *= yy;
    cout << xx << " * " << yy << " = " << zz << " ... " << vv << endl;
    cout << "O.K." << endl;
}
 
zalg/mult.txt · Last modified: 2021/05/12 16:54 by 88.103.111.44
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki