math: add sin and cos 1.12 fixed point functions.

This commit is contained in:
Zack Buhman 2024-09-03 00:12:12 -05:00
parent 3b7a18bb5d
commit 14c5ecb076
7 changed files with 177 additions and 1 deletions

3
.gitignore vendored
View File

@ -7,4 +7,5 @@ __pycache__
*.nds *.nds
.~lock* .~lock*
*.csv *.csv
*.dsi *.dsi
*.out

95
math/cos_table_fp12.c Normal file
View File

@ -0,0 +1,95 @@
#include <stdint.h>
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
};

21
math/gen_cos_table.py Normal file
View File

@ -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 <stdint.h>")
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("};")

10
math/math.h Normal file
View File

@ -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);
}

23
math/sincos.c Normal file
View File

@ -0,0 +1,23 @@
#include <stdint.h>
#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];
}
}

10
math/sincos_test.c Normal file
View File

@ -0,0 +1,10 @@
#include <stdio.h>
#include "math.h"
int main()
{
for (int i = -360; i <= 360; i++) {
printf("%d %d\n", i, sin_fp12(i));
}
}

16
math/sincos_verify.py Normal file
View File

@ -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)