====== Násobení čísel typu float ====== #include #include 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; }