diff --git a/.gitignore b/.gitignore index 257c669..176e8a9 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ __pycache__ *.nds .~lock* *.csv -*.dsi \ No newline at end of file +*.dsi +*.out diff --git a/math/cos_table_fp12.c b/math/cos_table_fp12.c new file mode 100644 index 0000000..50f8b43 --- /dev/null +++ b/math/cos_table_fp12.c @@ -0,0 +1,95 @@ +#include + +const uint16_t cos_table_fp12[91] = { + 4096, + 4095, + 4093, + 4090, + 4086, + 4080, + 4073, + 4065, + 4056, + 4045, + 4033, + 4020, + 4006, + 3991, + 3974, + 3956, + 3937, + 3917, + 3895, + 3872, + 3848, + 3823, + 3797, + 3770, + 3741, + 3712, + 3681, + 3649, + 3616, + 3582, + 3547, + 3510, + 3473, + 3435, + 3395, + 3355, + 3313, + 3271, + 3227, + 3183, + 3137, + 3091, + 3043, + 2995, + 2946, + 2896, + 2845, + 2793, + 2740, + 2687, + 2632, + 2577, + 2521, + 2465, + 2407, + 2349, + 2290, + 2230, + 2170, + 2109, + 2048, + 1985, + 1922, + 1859, + 1795, + 1731, + 1665, + 1600, + 1534, + 1467, + 1400, + 1333, + 1265, + 1197, + 1129, + 1060, + 990, + 921, + 851, + 781, + 711, + 640, + 570, + 499, + 428, + 356, + 285, + 214, + 142, + 71, + 0 +}; diff --git a/math/gen_cos_table.py b/math/gen_cos_table.py new file mode 100644 index 0000000..cd37639 --- /dev/null +++ b/math/gen_cos_table.py @@ -0,0 +1,21 @@ +from math import cos, pi + +fixed_point_bits = 12 +divisor = 2 ** fixed_point_bits +tau = pi * 2 + +if __name__ == "__main__": + print("#include ") + print() + print(f"const uint16_t cos_table_fp{fixed_point_bits}[91] = {{") + for i in range(0, 91): + radians = i / 360 * tau + n = cos(radians) + assert n >= 0 + integer = int(n) + decimal = int((n - integer) * divisor) + assert decimal < divisor + fixed_point = (integer * divisor) + decimal + comma = "" if i == 90 else "," + print(f" {fixed_point}{comma}") + print("};") diff --git a/math/math.h b/math/math.h new file mode 100644 index 0000000..ace35d0 --- /dev/null +++ b/math/math.h @@ -0,0 +1,10 @@ +#pragma once + +#define abs __builtin_abs + +int cos_fp12(int theta); + +static inline int sin_fp12(int theta) +{ + return cos_fp12(theta - 90); +} diff --git a/math/sincos.c b/math/sincos.c new file mode 100644 index 0000000..4ebfe48 --- /dev/null +++ b/math/sincos.c @@ -0,0 +1,23 @@ +#include + +#include "math.h" + +extern const uint16_t cos_table_fp12[]; + +int cos_fp12(int theta) +{ + theta = abs(theta); + while (theta > 360) { + theta -= 360; + } + + if (theta <= 90) { + return cos_table_fp12[theta]; + } else if (theta <= 180) { + return - cos_table_fp12[180 - theta]; + } else if (theta <= 270) { + return - cos_table_fp12[theta - 180]; + } else { + return cos_table_fp12[360 - theta]; + } +} diff --git a/math/sincos_test.c b/math/sincos_test.c new file mode 100644 index 0000000..a6c7b39 --- /dev/null +++ b/math/sincos_test.c @@ -0,0 +1,10 @@ +#include + +#include "math.h" + +int main() +{ + for (int i = -360; i <= 360; i++) { + printf("%d %d\n", i, sin_fp12(i)); + } +} diff --git a/math/sincos_verify.py b/math/sincos_verify.py new file mode 100644 index 0000000..8777bd8 --- /dev/null +++ b/math/sincos_verify.py @@ -0,0 +1,16 @@ +from math import cos, sin + +import sys +from gen_cos_table import fixed_point_bits, divisor, tau + +for i in range(-360, 360 + 1): + line = sys.stdin.readline() + ix, value = map(int, line.strip().split()) + assert i == ix + radians = i / 360 * tau + n = sin(radians) + integer = int(n) + decimal = int((n - integer) * divisor) + fixed_point = (integer * divisor) + decimal + if fixed_point != value: + print("error", i, fixed_point, value)