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 c98b178040
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,
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
};

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 = 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("};")

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 = int(n)
decimal = int((n - integer) * divisor)
fixed_point = (integer * divisor) + decimal
if fixed_point != value:
print("error", i, fixed_point, value)