diff --git a/README.md b/README.md index 54ac0d1..87b6906 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,8 @@ Don't. The makefile only includes a test target, because I want to test my code. silly silly_zeros(); // creates a fixed point value of zero silly silly_add(silly, silly); // addition -silly silly_sub(silly, silly); // subtracttion +silly silly_sub(silly, silly); // subtraction +silly silly_mul(silly, silly); // multiplication char* silly_to_string(silly); // converts a fixed point value to a string (memory is now yours) ``` diff --git a/silly.c b/silly.c index dc7a599..81d1d33 100644 --- a/silly.c +++ b/silly.c @@ -24,7 +24,7 @@ silly silly_add(silly x, silly y) { z.before = x.before + y.before; z.after = x.after + y.after; - if (z.after < x.after && z.after < y.after) z.before += 1; + if (z.after < x.after && z.after < y.after) z.before++; return z; } @@ -53,7 +53,26 @@ silly silly_sub(silly x, silly y) { z.after = x.after - y.after; - if (z.after > x.after) z.before -= 1; + if (z.after > x.after) z.before--; + + return z; +} + +silly silly_mul(silly x, silly y) { + silly z = silly_zeros(); + + z.sign = x.sign ^ y.sign; + + uint64_t t0 = (x.before * y.after); + uint64_t t1 = (y.before * x.after); + z.before = x.before * y.before + (t0>>32) + (t1>>32); + uint32_t t0b = t0&0xffffffff; + uint32_t t1b = t1&0xffffffff; + uint32_t tsum = t0b + t1b; + if (tsum < t0b || tsum < t1b) z.before++; + z.after = x.after * y.after + tsum; + + if (z.after < tsum) z.before++; return z; } diff --git a/silly.h b/silly.h index b4499b2..b514477 100644 --- a/silly.h +++ b/silly.h @@ -12,6 +12,7 @@ silly silly_zeros(); silly silly_add(silly, silly); silly silly_sub(silly, silly); +silly silly_mul(silly, silly); //silly silly_from_8(float8_t); //silly silly_from_16(float16_t); diff --git a/tests/test.c b/tests/test.c index 889cdc4..7160c50 100644 --- a/tests/test.c +++ b/tests/test.c @@ -67,11 +67,37 @@ TEST silly_subtraction() { PASS(); } +TEST silly_multiplication() { + silly x = silly_zeros(); + x.sign = 1; + x.before = 3; + silly y = silly_zeros(); + y.before = 2; + x = silly_mul(x, y); + + ASSERT_EQ_FMT(1, x.sign, "%d"); + ASSERT_EQ_FMT(6, x.before, "%d"); + ASSERT_EQ_FMT(0, x.after, "%d"); + + x = silly_zeros(); + x.before = 3; + x.after = 0xffffffff; + y = silly_zeros(); + y.before = 2; + x = silly_mul(x, y); + + ASSERT_EQ_FMT(7, x.before, "%d"); + ASSERT_EQ_FMT(0, x.after, "%d"); + + PASS(); +} + SUITE(tests) { RUN_TEST(silly_zeros_is_zero); RUN_TEST(silly_string); RUN_TEST(silly_addition); RUN_TEST(silly_subtraction); + RUN_TEST(silly_multiplication); } GREATEST_MAIN_DEFS();