#include "silleee.h" silleee silleee_sub(silleee x, silleee y) { y ^= 0x80000000; return silleee_add(x, y); } silleee shift_and_round(int val, int bits) { static unsigned masks[24]= { 0, 1, 3, 7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff, 0x7ff, 0xfff, 0x1fff, 0x3fff, 0x7fff, 0xffff, 0x1ffff, 0x3ffff, 0x7ffff, 0xfffff, 0x1fffff, 0x3fffff, 0x7fffff }; static unsigned masks_ho[24] = { 0, 1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000, 0x10000, 0x20000, 0x40000, 0x80000, 0x100000, 0x200000, 0x400000 }; int so = val & masks[bits]; val >>= bits; if (so > masks_ho[bits]) val++; else if(so == masks_ho[bits]) val += val&1; return val; } silleee silleee_add(silleee x, silleee y) { int dexp; long unsigned dmant; int dsign; int xexp = exponent(x); long unsigned xmant = mantissa(x); int xsign = sign(x); int yexp = exponent(y); long unsigned ymant = mantissa(y); int ysign = sign(y); if (xexp == 127) { if (!xmant) { if (yexp == 127) { if(!ymant) return xsign == ysign ? y : 0x7fc00000; else return y; } } else { return x; } } else if (yexp == 127) { return y; } dexp = yexp; if (yexp > xexp) { xmant = shift_and_round(xmant, yexp-xexp); } else if (yexp < xexp) { ymant = shift_and_round(ymant, xexp-yexp); dexp = xexp; } if (ysign ^ xsign) { if (xmant > ymant) { dmant = xmant - ymant; dsign = xmant; } else { dmant = ymant - xmant; dsign = ysign; } } else { dsign = xsign; dmant = xmant + ymant; } if (dmant >= 0x1000000) { dmant = shift_and_round(dmant, 1); ++dexp; } else { if (dmant) { while ((dmant < 0x800000) && (dexp > -127)) { dmant <<= 1; --dexp; } } else { dsign = 0; dexp = 0; } } return pack_silleee(dsign, dexp, dmant); }