#include <stdio.h>
#include <limits.h>
#if UINT_MAX >= 0xFFFFFFFF
typedef unsigned myfloat;
#else
typedef unsigned long myfloat;
#endif
#define MF_EXP_BIAS 0x80
myfloat mfadd(myfloat a, myfloat b)
{
unsigned ea = a >> 16, eb = b >> 16;
if (ea > eb)
{
a &= 0xFFFF;
b = (b & 0xFFFF) >> (ea - eb);
if ((a += b) > 0xFFFF)
a >>= 1, ++ea;
return a | ((myfloat)ea << 16);
}
else if (eb > ea)
{
b &= 0xFFFF;
a = (a & 0xFFFF) >> (eb - ea);
if ((b += a) > 0xFFFF)
b >>= 1, ++eb;
return b | ((myfloat)eb << 16);
}
else
{
return (((a & 0xFFFF) + (b & 0xFFFF)) >> 1) | ((myfloat)++ea << 16);
}
}
myfloat mfmul(myfloat a, myfloat b)
{
unsigned ea = a >> 16, eb = b >> 16, e = ea + eb - MF_EXP_BIAS;
myfloat p = ((a & 0xFFFF) * (b & 0xFFFF)) >> 16;
return p | ((myfloat)e << 16);
}
myfloat double2mf(double x)
{
myfloat f;
unsigned e = MF_EXP_BIAS + 16;
if (x <= 0)
return 0;
while (x < 0x8000)
x *= 2, --e;
while (x >= 0x10000)
x /= 2, ++e;
f = x;
return f | ((myfloat)e << 16);
}
double mf2double(myfloat f)
{
double x;
unsigned e = (f >> 16) - 16;
if ((f & 0xFFFF) == 0)
return 0;
x = f & 0xFFFF;
while (e > MF_EXP_BIAS)
x *= 2, --e;
while (e < MF_EXP_BIAS)
x /= 2, ++e;
return x;
}
int main(void)
{
double testConvData[] = { 1e-18, .25, 0.3333333, .5, 1, 2, 3.141593, 1e18 };
unsigned i;
for (i = 0; i < sizeof(testConvData) / sizeof(testConvData[0]); i++)
printf("%e -> 0x%06lX -> %e\n", testConvData[i],
(unsigned long)double2mf(testConvData[i]),
mf2double(double2mf(testConvData[i])));
printf("300 * 5 = %e\n", mf2double
(mfmul
(double2mf
(300),double2mf
(5)))); printf("500 + 3 = %e\n", mf2double
(mfadd
(double2mf
(500),double2mf
(3)))); printf("1e18 * 1e-18 = %e\n", mf2double
(mfmul
(double2mf
(1e18),double2mf
(1e-18)))); printf("1e-18 + 2e-18 = %e\n", mf2double
(mfadd
(double2mf
(1e-18),double2mf
(2e-18)))); printf("1e-16 + 1e-18 = %e\n", mf2double
(mfadd
(double2mf
(1e-16),double2mf
(1e-18))));
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxsaW1pdHMuaD4KCiNpZiBVSU5UX01BWCA+PSAweEZGRkZGRkZGCnR5cGVkZWYgdW5zaWduZWQgbXlmbG9hdDsKI2Vsc2UKdHlwZWRlZiB1bnNpZ25lZCBsb25nIG15ZmxvYXQ7CiNlbmRpZgoKI2RlZmluZSBNRl9FWFBfQklBUyAweDgwCgpteWZsb2F0IG1mYWRkKG15ZmxvYXQgYSwgbXlmbG9hdCBiKQp7CiAgdW5zaWduZWQgZWEgPSBhID4+IDE2LCBlYiA9IGIgPj4gMTY7CiAgaWYgKGVhID4gZWIpCiAgewogICAgYSAmPSAweEZGRkY7CiAgICBiID0gKGIgJiAweEZGRkYpID4+IChlYSAtIGViKTsKICAgIGlmICgoYSArPSBiKSA+IDB4RkZGRikKICAgICAgYSA+Pj0gMSwgKytlYTsKICAgIHJldHVybiBhIHwgKChteWZsb2F0KWVhIDw8IDE2KTsKICB9CiAgZWxzZSBpZiAoZWIgPiBlYSkKICB7CiAgICBiICY9IDB4RkZGRjsKICAgIGEgPSAoYSAmIDB4RkZGRikgPj4gKGViIC0gZWEpOwogICAgaWYgKChiICs9IGEpID4gMHhGRkZGKQogICAgICBiID4+PSAxLCArK2ViOwogICAgcmV0dXJuIGIgfCAoKG15ZmxvYXQpZWIgPDwgMTYpOwogIH0KICBlbHNlCiAgewogICAgcmV0dXJuICgoKGEgJiAweEZGRkYpICsgKGIgJiAweEZGRkYpKSA+PiAxKSB8ICgobXlmbG9hdCkrK2VhIDw8IDE2KTsKICB9Cn0KCm15ZmxvYXQgbWZtdWwobXlmbG9hdCBhLCBteWZsb2F0IGIpCnsKICB1bnNpZ25lZCBlYSA9IGEgPj4gMTYsIGViID0gYiA+PiAxNiwgZSA9IGVhICsgZWIgLSBNRl9FWFBfQklBUzsKICBteWZsb2F0IHAgPSAoKGEgJiAweEZGRkYpICogKGIgJiAweEZGRkYpKSA+PiAxNjsKICByZXR1cm4gcCB8ICgobXlmbG9hdCllIDw8IDE2KTsKfQoKbXlmbG9hdCBkb3VibGUybWYoZG91YmxlIHgpCnsKICBteWZsb2F0IGY7CiAgdW5zaWduZWQgZSA9IE1GX0VYUF9CSUFTICsgMTY7CiAgaWYgKHggPD0gMCkKICAgIHJldHVybiAwOwogIHdoaWxlICh4IDwgMHg4MDAwKQogICAgeCAqPSAyLCAtLWU7CiAgd2hpbGUgKHggPj0gMHgxMDAwMCkKICAgIHggLz0gMiwgKytlOwogIGYgPSB4OwogIHJldHVybiBmIHwgKChteWZsb2F0KWUgPDwgMTYpOwp9Cgpkb3VibGUgbWYyZG91YmxlKG15ZmxvYXQgZikKewogIGRvdWJsZSB4OwogIHVuc2lnbmVkIGUgPSAoZiA+PiAxNikgLSAxNjsKICBpZiAoKGYgJiAweEZGRkYpID09IDApCiAgICByZXR1cm4gMDsKICB4ID0gZiAmIDB4RkZGRjsKICB3aGlsZSAoZSA+IE1GX0VYUF9CSUFTKQogICAgeCAqPSAyLCAtLWU7CiAgd2hpbGUgKGUgPCBNRl9FWFBfQklBUykKICAgIHggLz0gMiwgKytlOwogIHJldHVybiB4Owp9CgppbnQgbWFpbih2b2lkKQp7CiAgZG91YmxlIHRlc3RDb252RGF0YVtdID0geyAxZS0xOCwgLjI1LCAwLjMzMzMzMzMsIC41LCAxLCAyLCAzLjE0MTU5MywgMWUxOCB9OwogIHVuc2lnbmVkIGk7CiAgZm9yIChpID0gMDsgaSA8IHNpemVvZih0ZXN0Q29udkRhdGEpIC8gc2l6ZW9mKHRlc3RDb252RGF0YVswXSk7IGkrKykKICAgIHByaW50ZigiJWUgLT4gMHglMDZsWCAtPiAlZVxuIiwKICAgICAgICAgICB0ZXN0Q29udkRhdGFbaV0sCiAgICAgICAgICAgKHVuc2lnbmVkIGxvbmcpZG91YmxlMm1mKHRlc3RDb252RGF0YVtpXSksCiAgICAgICAgICAgbWYyZG91YmxlKGRvdWJsZTJtZih0ZXN0Q29udkRhdGFbaV0pKSk7CgogIHByaW50ZigiMzAwICogNSA9ICVlXG4iLCBtZjJkb3VibGUobWZtdWwoZG91YmxlMm1mKDMwMCksZG91YmxlMm1mKDUpKSkpOwogIHByaW50ZigiNTAwICsgMyA9ICVlXG4iLCBtZjJkb3VibGUobWZhZGQoZG91YmxlMm1mKDUwMCksZG91YmxlMm1mKDMpKSkpOwogIHByaW50ZigiMWUxOCAqIDFlLTE4ID0gJWVcbiIsIG1mMmRvdWJsZShtZm11bChkb3VibGUybWYoMWUxOCksZG91YmxlMm1mKDFlLTE4KSkpKTsKICBwcmludGYoIjFlLTE4ICsgMmUtMTggPSAlZVxuIiwgbWYyZG91YmxlKG1mYWRkKGRvdWJsZTJtZigxZS0xOCksZG91YmxlMm1mKDJlLTE4KSkpKTsKICBwcmludGYoIjFlLTE2ICsgMWUtMTggPSAlZVxuIiwgbWYyZG91YmxlKG1mYWRkKGRvdWJsZTJtZigxZS0xNiksZG91YmxlMm1mKDFlLTE4KSkpKTsKCiAgcmV0dXJuIDA7Cn0K