initial
This commit is contained in:
7
Makefile
Normal file
7
Makefile
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
LIBFILES=silly.c
|
||||||
|
TESTFILES=$(wildcard tests/*.c)
|
||||||
|
|
||||||
|
test:
|
||||||
|
gcc $(LIBFILES) $(TESTFILES) -o test_silly
|
||||||
|
./test_silly
|
||||||
|
rm test_silly
|
25
README.md
Normal file
25
README.md
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# silly
|
||||||
|
|
||||||
|
A toy library implementing fixed-point arithmetic.
|
||||||
|
Please don't use it, the name is descriptive.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Don't. The makefile only includes a test target, because I want to test my code.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```c
|
||||||
|
silly silly_zeros(); // creates a fixed point value of zero
|
||||||
|
|
||||||
|
silly silly_add(silly, silly); // addition
|
||||||
|
silly silly_sub(silly, silly); // subtracttion
|
||||||
|
|
||||||
|
char* silly_to_string(silly); // converts a fixed point value to a string (memory is now yours)
|
||||||
|
```
|
||||||
|
|
||||||
|
That's it!
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
Have fun!
|
67
silly.c
Normal file
67
silly.c
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
#include "silly.h"
|
||||||
|
|
||||||
|
silly silly_zeros() {
|
||||||
|
silly s;
|
||||||
|
s.sign = 0;
|
||||||
|
s.before = 0;
|
||||||
|
s.after = 0;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
silly silly_add(silly x, silly y) {
|
||||||
|
if (x.sign ^ y.sign) {
|
||||||
|
if (x.sign) {
|
||||||
|
x.sign = 0;
|
||||||
|
return silly_sub(y, x);
|
||||||
|
}
|
||||||
|
y.sign = 0;
|
||||||
|
return silly_sub(x, y);
|
||||||
|
}
|
||||||
|
silly z = silly_zeros();
|
||||||
|
|
||||||
|
z.sign = x.sign | y.sign;
|
||||||
|
// Note: Overflow
|
||||||
|
z.before = x.before + y.before;
|
||||||
|
z.after = x.after + y.after;
|
||||||
|
|
||||||
|
if (z.after < x.after && z.after < y.after) z.before += 1;
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
silly silly_sub(silly x, silly y) {
|
||||||
|
if (y.sign) {
|
||||||
|
y.sign = 0;
|
||||||
|
return silly_add(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x.sign) {
|
||||||
|
x.sign = 0;
|
||||||
|
x = silly_add(x, y);
|
||||||
|
x.sign = 1;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
silly z = silly_zeros();
|
||||||
|
|
||||||
|
// Note: Underflow
|
||||||
|
z.before = x.before - y.before;
|
||||||
|
|
||||||
|
if (z.before > x.before) {
|
||||||
|
z.sign = 1;
|
||||||
|
z.before = 0xffffffff - z.before + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
z.after = x.after - y.after;
|
||||||
|
|
||||||
|
if (z.after > x.after) z.before -= 1;
|
||||||
|
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* silly_to_string(silly s) {
|
||||||
|
char* res = malloc(23);
|
||||||
|
|
||||||
|
snprintf(res, 23, "%s%010d.%010d", s.sign? "-" : "+", s.before, s.after);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
23
silly.h
Normal file
23
silly.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned sign :1;
|
||||||
|
unsigned before :31;
|
||||||
|
unsigned after :32;
|
||||||
|
} silly;
|
||||||
|
|
||||||
|
silly silly_zeros();
|
||||||
|
|
||||||
|
silly silly_add(silly, silly);
|
||||||
|
silly silly_sub(silly, silly);
|
||||||
|
|
||||||
|
//silly silly_from_8(float8_t);
|
||||||
|
//silly silly_from_16(float16_t);
|
||||||
|
//silly silly_from_32(float32_t);
|
||||||
|
//silly silly_from_64(float64_t);
|
||||||
|
//
|
||||||
|
//float64_t silly_to_64(silly);
|
||||||
|
|
||||||
|
char* silly_to_string(silly);
|
1040
tests/greatest.h
Normal file
1040
tests/greatest.h
Normal file
File diff suppressed because it is too large
Load Diff
85
tests/test.c
Normal file
85
tests/test.c
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
#include "greatest.h"
|
||||||
|
#include "../silly.h"
|
||||||
|
|
||||||
|
TEST silly_zeros_is_zero() {
|
||||||
|
silly x = silly_zeros();
|
||||||
|
|
||||||
|
ASSERT_EQ_FMT(0, x.sign, "%d");
|
||||||
|
ASSERT_EQ_FMT(0, x.before, "%d");
|
||||||
|
ASSERT_EQ_FMT(0, x.after, "%d");
|
||||||
|
PASS();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST silly_string() {
|
||||||
|
silly x = silly_zeros();
|
||||||
|
|
||||||
|
ASSERT_STR_EQ("+0000000000.0000000000", silly_to_string(x));
|
||||||
|
x.before = 1;
|
||||||
|
ASSERT_STR_EQ("+0000000001.0000000000", silly_to_string(x));
|
||||||
|
PASS();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST silly_addition() {
|
||||||
|
silly x = silly_zeros();
|
||||||
|
x.before = 1;
|
||||||
|
x.after = 1;
|
||||||
|
silly y = silly_zeros();
|
||||||
|
y.before = 1;
|
||||||
|
y.after = 0xffffffff;
|
||||||
|
x = silly_add(x, y);
|
||||||
|
|
||||||
|
ASSERT_EQ_FMT(3, x.before, "%d");
|
||||||
|
ASSERT_EQ_FMT(0, x.after, "%d");
|
||||||
|
|
||||||
|
y = silly_zeros();
|
||||||
|
y.sign = 1;
|
||||||
|
y.before = 4;
|
||||||
|
x = silly_add(x, y);
|
||||||
|
|
||||||
|
ASSERT_EQ_FMT(1, x.sign, "%d");
|
||||||
|
ASSERT_EQ_FMT(1, x.before, "%d");
|
||||||
|
ASSERT_EQ_FMT(0, x.after, "%d");
|
||||||
|
|
||||||
|
PASS();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST silly_subtraction() {
|
||||||
|
silly x = silly_zeros();
|
||||||
|
x.before = 2;
|
||||||
|
silly y = silly_zeros();
|
||||||
|
y.before = 1;
|
||||||
|
y.after = 0xffffffff;
|
||||||
|
x = silly_sub(x, y);
|
||||||
|
|
||||||
|
ASSERT_EQ_FMT(0, x.before, "%d");
|
||||||
|
ASSERT_EQ_FMT(1, x.after, "%d");
|
||||||
|
|
||||||
|
x = silly_zeros();
|
||||||
|
x.before = 2;
|
||||||
|
y = silly_zeros();
|
||||||
|
y.sign = 1;
|
||||||
|
y.before = 4;
|
||||||
|
x = silly_sub(x, y);
|
||||||
|
|
||||||
|
ASSERT_EQ_FMT(6, 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
GREATEST_MAIN_DEFS();
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
GREATEST_MAIN_BEGIN();
|
||||||
|
|
||||||
|
RUN_SUITE(tests);
|
||||||
|
|
||||||
|
GREATEST_MAIN_END();
|
||||||
|
}
|
Reference in New Issue
Block a user