[openfirmware] [commit] r2995 - forth/lib
repository service
svn at openfirmware.info
Fri Jun 1 20:31:33 CEST 2012
Author: wmb
Date: Fri Jun 1 20:31:33 2012
New Revision: 2995
URL: http://tracker.coreboot.org/trac/openfirmware/changeset/2995
Log:
isin.fth - before svn 2994, the calculation in set-period was using */, which is supposed to use a double-precision intermediate value to avoid overflow. However, */ is not a primitive FCode, so the FCode tokenizer was synthesizing it (incorrectly) using (overflowing) * and /. The correct fix, to retain precision, is to implement "u*/" using (double-precision) um* and um/mod .
Modified:
forth/lib/isin.fth
Modified: forth/lib/isin.fth
==============================================================================
--- forth/lib/isin.fth Fri Jun 1 14:21:35 2012 (r2994)
+++ forth/lib/isin.fth Fri Jun 1 20:31:33 2012 (r2995)
@@ -27,17 +27,17 @@
2/ dup to #cycle/2
2/ to #cycle/4
;
+: u*/ ( u1 unum udenom -- u2 ) >r um* r> um/mod nip ;
: set-period ( cycle/4 -- )
dup to #cycle/4 ( cycle/4 )
2* dup to #cycle/2 ( cycle/2 )
2* dup to #cycle ( cycle )
fs over / to freq ( period )
- pi swap / fs * to fstep ( )
+ pi fs rot u*/ to fstep ( )
;
\ Multiply two fractional numbers where the scale factor is 2^15
-\ : times ( n1 n2 -- n3 ) d# 32767 */ ; \ Insignificantly more accurate, but slower
-: times ( n1 n2 -- n3 ) * d# 15 rshift ;
+: times ( n1 n2 -- n3 ) d# 32767 u*/ ;
\ Computes (1 - (theta^2 / divisor) * last)
: sin-step ( last divisor -- next ) thetasq swap / times one min one swap - ;
@@ -48,7 +48,7 @@
\ 1 - (t^2/(1*2)) * (1 - (t^2/(3*4)) * (1 - (t^2/(5*6)) * (1 - (t^2/(7*8))))
: icos ( index -- frac )
- fstep fs 2/ */ to theta
+ fstep fs 2/ u*/ to theta
theta dup times to thetasq
one d# 90 cos-step d# 56 cos-step d# 30 cos-step d# 12 cos-step 2 cos-step one min
;
@@ -59,7 +59,7 @@
\ theta * (1 - (theta^2/(2*3)) * (1 - (theta^2/(4*5)) * (1 - (theta^2/(6*7)) * (1 - (theta^2/(8*9))))))
\ This is good for the first quadrant only, i.e. 0 <= index <= fs / freq / 4
: calc-sin ( index -- frac )
- fstep fs 2/ */ to theta
+ fstep fs 2/ u*/ to theta
theta dup times to thetasq
one d# 72 sin-step d# 42 sin-step d# 20 sin-step 6 sin-step theta times one min
;
More information about the openfirmware
mailing list