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..11d2352 --- /dev/null +++ b/math/cos_table_fp12.c @@ -0,0 +1,95 @@ +#include + +const uint16_t cos_table_fp12[91] = { + 4096, + 4095, + 4094, + 4090, + 4086, + 4080, + 4074, + 4065, + 4056, + 4046, + 4034, + 4021, + 4006, + 3991, + 3974, + 3956, + 3937, + 3917, + 3896, + 3873, + 3849, + 3824, + 3798, + 3770, + 3742, + 3712, + 3681, + 3650, + 3617, + 3582, + 3547, + 3511, + 3474, + 3435, + 3396, + 3355, + 3314, + 3271, + 3228, + 3183, + 3138, + 3091, + 3044, + 2996, + 2946, + 2896, + 2845, + 2793, + 2741, + 2687, + 2633, + 2578, + 2522, + 2465, + 2408, + 2349, + 2290, + 2231, + 2171, + 2110, + 2048, + 1986, + 1923, + 1860, + 1796, + 1731, + 1666, + 1600, + 1534, + 1468, + 1401, + 1334, + 1266, + 1198, + 1129, + 1060, + 991, + 921, + 852, + 782, + 711, + 641, + 570, + 499, + 428, + 357, + 286, + 214, + 143, + 71, + 0 +}; diff --git a/math/gen_cos_table.py b/math/gen_cos_table.py new file mode 100644 index 0000000..35af185 --- /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 = round(n) + decimal = round((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..70be67a --- /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 = round(n) + decimal = round((n - integer) * divisor) + fixed_point = (integer * divisor) + decimal + if fixed_point != value: + print("error", i, fixed_point, value)