starkernel: item 4.3.3a -- Q48.16 trigonometry (Q.SIN/Q.COS)
Adds q48_reduce_angle() (range-reduce a signed Q48.16 angle into [-PI_Q48, PI_Q48] via one integer division plus a bounded fix-up loop) and q48_sin_approx/q48_cos_approx (Taylor series, terms n=3,5,7,9,11 for sin and n=2,4,6,8,10 for cos, early exit below 10). Q.SIN/Q.COS registered as FORTH words in q48_words.c, same pattern as Q.LOG/Q.EXP/Q.SQRT. Found mid-implementation: this codebase has two independent Q48.16 implementations -- src/word_source/q48_16_words.c (hosted/vendored) and src/starkernel/math/q48_16.c (kernel-only; the kernel build does not compile the former at all). The hosted build linked fine after the first pass; the kernel build failed with undefined references until the same two functions were added to both .c files and both q48_16.h headers (include/q48_16.h and include/starkernel/q48_16.h). Not fixed at the root -- Q.LOG/Q.EXP/Q.SQRT already had this same four-file duplication, unremarked until now -- just navigated correctly for this item. Verified live on amd64 via serial injection: sin/cos at 0, +-pi/2, pi, and 3pi (range-reduction across multiple turns) all match expected values within Taylor-series truncation error (<0.2%). All three architectures boot clean to ok> with the DoE completing; dict_hash identical across all three (0x291a660b05fa7b52). FABRIC.md item 4.3.3a marked done with full acceptance evidence.
This commit is contained in:
@@ -24,6 +24,8 @@
|
||||
* Q.LOG ( q -- ln_q ) natural log, Newton-Raphson
|
||||
* Q.EXP ( q -- e^q ) Taylor series
|
||||
* Q.SQRT ( q -- sqrt_q ) Newton-Raphson
|
||||
* Q.SIN ( q -- sin_q ) Taylor series, radians, any magnitude
|
||||
* Q.COS ( q -- cos_q ) Taylor series, radians, any magnitude
|
||||
* Q.FROM-INT ( n -- q ) integer → Q48.16 (n << 16)
|
||||
* Q.TO-INT ( q -- n ) Q48.16 → integer (q >> 16, truncate)
|
||||
* Q.1 ( -- 65536 ) 1.0 in Q48.16
|
||||
@@ -115,6 +117,16 @@ static void q48_word_sqrt(VM *vm)
|
||||
q48_push(vm, q48_sqrt_approx(q48_pop(vm)));
|
||||
}
|
||||
|
||||
static void q48_word_sin(VM *vm)
|
||||
{
|
||||
q48_push(vm, q48_sin_approx(q48_pop(vm)));
|
||||
}
|
||||
|
||||
static void q48_word_cos(VM *vm)
|
||||
{
|
||||
q48_push(vm, q48_cos_approx(q48_pop(vm)));
|
||||
}
|
||||
|
||||
/* ── conversions ─────────────────────────────────────────────────────── */
|
||||
|
||||
static void q48_word_from_int(VM *vm)
|
||||
@@ -208,6 +220,8 @@ void register_q48_words(VM *vm)
|
||||
register_word(vm, "Q.LOG", q48_word_log);
|
||||
register_word(vm, "Q.EXP", q48_word_exp);
|
||||
register_word(vm, "Q.SQRT", q48_word_sqrt);
|
||||
register_word(vm, "Q.SIN", q48_word_sin);
|
||||
register_word(vm, "Q.COS", q48_word_cos);
|
||||
register_word(vm, "Q.FROM-INT", q48_word_from_int);
|
||||
register_word(vm, "Q.TO-INT", q48_word_to_int);
|
||||
register_word(vm, "Q.1", q48_word_one);
|
||||
|
||||
Reference in New Issue
Block a user