#include typedef union { unsigned d; float f; } FD; void float_sabiranje(float x, float y, float * R) { FD fdx, fdy, fdr; unsigned mx, my, sx, sy, m, s; int ex, ey, e; /* Ucitavamo u unijske promenljive vrednosti brojeva x i y. Na dalje ce ovim vrednostima biti pristupano preko clana d, koji je tipa unsigned */ fdx.f = x; fdy.f = y; /* Ako je prvi sabirak nula ili denormalizovan broj, vracamo drugi sabirak. */ if((fdx.d & 0x7F800000) == 0) { *R = y; return; } /* Simetricno, ako je drugi sabirak nula ili denormalizovan broj. */ if((fdy.d & 0x7F800000) == 0) { *R = x; return; } /* Izdvajamo bitove mantise, a zatim ukljucujemo i implicitnu jedinicu. */ mx = (fdx.d & 0x7FFFFF) | 0x800000; my = (fdy.d & 0x7FFFFF) | 0x800000; /* Odredjujemo vrednosti eksponenata */ ex = (int)((fdx.d & 0x7F800000) >> 23) - 127; ey = (int)((fdy.d & 0x7F800000) >> 23) - 127; /* Izdvajamo bitove znaka */ sx = (fdx.d & 0x80000000); sy = (fdy.d & 0x80000000); /* Ako je ex < ey, tada se mantisa uzastopno deli sa dva a eksponent uvecava za jedan, dok ne bude ex == ey */ while(ex < ey) { mx >>= 1; ex++; } /* Simetricno, ako je ey < ex */ while(ey < ex) { my >>= 1; ey++; } /* Ako su brojevi istog znaka, tada se mantise sabiraju, a znak rezultata je isti kao i znak operanada */ if(sx == sy) { m = mx + my; s = sx; } /* U suprotnom, ako je my > mx, tada oduzimamo my - mx, a znak je jednak znaku broja y. */ else if(my > mx) { m = my - mx; s = sy; } /* Slicno, ako je mx > my, tada je mantisa mx - my, a znak je jednak znaku broja x */ else { m = mx - my; s = sx; } /* Eksponent je jednak ujednacenom eksponentu operanada. */ e = ex; /* U nastavku vrsimo normalizaciju. Ako je nakon sabiranja dva 24-bitna cela broja (mx i my) dobijena 25-bitna vrednost, tada se m pomera u desno za jednu poziciju, a eksponent uvecava za jedan. */ if(m & 0x1000000) { m >>= 1; e++; /* Ako je nakon uvecanja eksponent 128, tada je doslo do prekoracenja. Rezultat je beskonacna vrednost, koja se predstavlja maksimalnim eksponentom i mantisom jednakom 0 */ if(e == 128) m = 0; } /* U suprotnom, broj je eventualno denormalizovan (bit na poziciji 23 je 0) pa treba pomerati u levo i umanjivati eksponent dok se ne dobije 1 na poziciji 23. Ukoliko eksponent postane jednak -127, tada broj ostaje denormalizovan (ili 0) */ else { while(!(m & 0x800000)) { m <<= 1; e--; if(e == -127) { m >>= 1; break; } } } /* Iskljucujemo implicitni bit 23 */ m &= 0x7FFFFF; /* Upisujemo mantisu i eksponent */ fdr.d = m; fdr.d |= (unsigned)(e + 127) << 23; fdr.d |= s; /* Upisujemo rezultat u za to predvidjenu lokaciju */ *R = fdr.f; } /* Za vezbu student moze da implementira sabiranje double podataka */ int main() { float x, y, R; scanf("%f%f", &x, &y); float_sabiranje(x, y, &R); printf("%g\n", R); return 0; }