-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfp.fs
67 lines (51 loc) · 1.93 KB
/
fp.fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
[undefined] fp.fs [if]
vocabulary fp.fs also fp.fs definitions
8 constant point \ fractional point
1 point lshift constant fp-bitmask
fp-bitmask 1- constant fp-fmask \ fractional bit mask
fp-fmask invert constant fp-imask \ integer bit mask
fp-bitmask 1 rshift constant fp.bit/2 \ 0.5 in fp
fp-bitmask negate fp-bitmask * constant max-fp \ maximum value
fp-bitmask negate fp-bitmask * constant min-fp \ minimum value
10 point lshift constant fp10
\ convert integer to fixed point
: i>fp ( n -- fp ) point lshift ;
\ convert fixed point to integer (rounded down)
: fp>i ( fp -- n ) point rshift ;
\ multiply two fixed point numbers
: fp* ( n0 n1 -- n2 ) fp-bitmask */ ;
\ divide two fixed point numbers
: fp/ ( n0 n1 -- n2 ) fp-bitmask swap */ ;
\ vector3 helper: convert 3 integers to 3 fixed point numbers
: i3>fp3 ( a b c -- a b c ) i>fp rot i>fp rot i>fp rot ;
\ vector3 helper: convert 3 fixed point numbers to 3 integers
: fp3>i3 ( a b c -- a b c ) fp>i rot fp>i rot fp>i rot ;
\ floor down fixed point number to nearest integer
: fpfloor ( n0 -- n1 ) fp-imask and ;
\ ceil up fixed point number to nearest integer
: fpceil ( n0 -- n1 ) fp-bitmask + fpfloor ;
\ round fixed point number to nearest integer
: fpround ( n0 -- n1 ) fp.bit/2 + fpfloor ;
\ return base 10 digits
: c10s ( a -- b ) 0 begin 1+ swap 10 / swap over 0> 0=
until swap drop ;
\ convert a decimal fractional number in the form integer fractional
: if>fp ( i f -- fp )
dup i>fp swap
c10s ( i f 10s )
0 do ( i f )
fp10 fp/
loop
swap i>fp +
;
\ supply the fractional digit count
: if2>fp ( i f c -- fp )
>r ( i f )
i>fp
r> 0 do ( i f )
fp10 fp/
loop
swap i>fp +
;
previous definitions
[endif]