mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Improve fixed-point documentation (#1455)
* Clarify the operator relationship of ordinary and fixed-point numbers * Attempt to clarify description of fixed-point numbers * Note that RGBASM does not check fixed-point precisions * Simplify sine table example a bit * Remove misleading equations describing `DIV`, `MUL`, and `FMOD` * Various minor style and formatting fixups
This commit is contained in:
99
man/rgbasm.5
99
man/rgbasm.5
@@ -369,23 +369,28 @@ equals $roman clz ( n )$.
|
|||||||
delim off
|
delim off
|
||||||
.EN
|
.EN
|
||||||
.Ss Fixed-point expressions
|
.Ss Fixed-point expressions
|
||||||
Fixed-point numbers are basically normal (32-bit) integers, which count fractions instead of whole numbers.
|
Fixed-point numbers are technically just integers, but conceptually they have a decimal point at a fixed location (hence the name).
|
||||||
They offer better precision than integers but limit the range of values.
|
This gives them increased precision, at the cost of a smaller range, while remaining far cheaper to manipulate than floating-point numbers (which
|
||||||
By default, the upper 16 bits are used for the integer part and the lower 16 bits are used for the fraction (65536ths).
|
.Nm
|
||||||
The default number of fractional bits can be changed with the
|
does not support).
|
||||||
|
.Pp
|
||||||
|
The default precision of all fixed-point numbers is 16 bits, meaning the lower 16 bits are used for the fractional part; so they count in 65536ths of 1.0.
|
||||||
|
This precision can be changed with the
|
||||||
.Fl Q
|
.Fl Q
|
||||||
command-line option.
|
command-line option, and/or by
|
||||||
You can also specify a precise fixed-point value by appending a
|
.Ic OPT Q
|
||||||
|
.Pq see Sx Changing options while assembling .
|
||||||
|
An individual fixed-point literal can specify its own precision, overriding the current default, by appending a
|
||||||
.Dq q
|
.Dq q
|
||||||
to it followed by the number of fractional bits, such as
|
followed by the number of fractional bits: for example,
|
||||||
.Ql 12.34q8 .
|
.Ql 1234.5q8
|
||||||
|
is equal to $0004d2_80
|
||||||
|
.EQ
|
||||||
|
delim $$
|
||||||
|
.EN
|
||||||
|
($= 1234.5 * 2 sup 8$).
|
||||||
.Pp
|
.Pp
|
||||||
Since fixed-point values are still just integers, you can use them in normal integer expressions.
|
Since fixed-point values are still just integers, you can use them in normal integer expressions.
|
||||||
Some integer operators like
|
|
||||||
.Sq +
|
|
||||||
and
|
|
||||||
.Sq -
|
|
||||||
don't care whether the operands are integers or fixed-point.
|
|
||||||
You can easily truncate a fixed-point number into an integer by shifting it right by the number of fractional bits.
|
You can easily truncate a fixed-point number into an integer by shifting it right by the number of fractional bits.
|
||||||
It follows that you can convert an integer to a fixed-point number by shifting it left that same amount.
|
It follows that you can convert an integer to a fixed-point number by shifting it left that same amount.
|
||||||
.Pp
|
.Pp
|
||||||
@@ -393,19 +398,16 @@ Note that the current number of fractional bits can be computed as
|
|||||||
.Ic TZCOUNT Ns Pq 1.0 .
|
.Ic TZCOUNT Ns Pq 1.0 .
|
||||||
.Pp
|
.Pp
|
||||||
The following functions are designed to operate with fixed-point numbers:
|
The following functions are designed to operate with fixed-point numbers:
|
||||||
.EQ
|
|
||||||
delim $$
|
|
||||||
.EN
|
|
||||||
.Bl -column -offset indent "ATAN2(y, x)"
|
.Bl -column -offset indent "ATAN2(y, x)"
|
||||||
.It Sy Name Ta Sy Operation
|
.It Sy Name Ta Sy Operation
|
||||||
.It Fn DIV x y Ta Fixed-point division $( x \[di] y ) \[mu] ( 2 ^ precision )$
|
.It Fn DIV x y Ta Fixed-point division
|
||||||
.It Fn MUL x y Ta Fixed-point multiplication $( x \[mu] y ) \[di] ( 2 ^ precision )$
|
.It Fn MUL x y Ta Fixed-point multiplication
|
||||||
.It Fn FMOD x y Ta Fixed-point modulo $( x % y ) \[di] ( 2 ^ precision )$
|
.It Fn FMOD x y Ta Fixed-point modulo
|
||||||
.It Fn POW x y Ta $x$ to the $y$ power
|
.It Fn POW x y Ta $x sup y$
|
||||||
.It Fn LOG x y Ta Logarithm of $x$ to the base $y$
|
.It Fn LOG x y Ta Logarithm of $x$ to the base $y$
|
||||||
.It Fn ROUND x Ta Round $x$ to the nearest integer
|
.It Fn ROUND x Ta Round $x$ to the nearest integer
|
||||||
.It Fn CEIL x Ta Round $x$ up to an integer
|
.It Fn CEIL x Ta Round $x$ up to the nearest integer
|
||||||
.It Fn FLOOR x Ta Round $x$ down to an integer
|
.It Fn FLOOR x Ta Round $x$ down to the nearest integer
|
||||||
.It Fn SIN x Ta Sine of $x$
|
.It Fn SIN x Ta Sine of $x$
|
||||||
.It Fn COS x Ta Cosine of $x$
|
.It Fn COS x Ta Cosine of $x$
|
||||||
.It Fn TAN x Ta Tangent of $x$
|
.It Fn TAN x Ta Tangent of $x$
|
||||||
@@ -418,7 +420,25 @@ delim $$
|
|||||||
delim off
|
delim off
|
||||||
.EN
|
.EN
|
||||||
.Pp
|
.Pp
|
||||||
All of these fixed-point functions can take an optional final argument, which is the precision to use.
|
There are no functions for fixed-point addition and subtraction, because the
|
||||||
|
.Sq +
|
||||||
|
and
|
||||||
|
.Sq -
|
||||||
|
operators can add and subtract pairs of fixed-point operands.
|
||||||
|
.Bd -ragged -offset indent
|
||||||
|
Note that some operators or functions are meaningful when combining integers and fixed-point values.
|
||||||
|
For example,
|
||||||
|
.Ql 2.0 * 3
|
||||||
|
is equivalent to
|
||||||
|
.Ql MUL(2.0, 3.0) ,
|
||||||
|
and
|
||||||
|
.Ql 6.0 / 2
|
||||||
|
is equivalent to
|
||||||
|
.Ql DIV(6.0, 2.0) .
|
||||||
|
Be careful and think about what the operations mean when doing this sort of thing.
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
All of these fixed-point functions can take an optional final argument, which is the precision to use for that one operation.
|
||||||
For example,
|
For example,
|
||||||
.Ql MUL(6.0q8, 7.0q8, 8)
|
.Ql MUL(6.0q8, 7.0q8, 8)
|
||||||
will evaluate to
|
will evaluate to
|
||||||
@@ -426,6 +446,12 @@ will evaluate to
|
|||||||
no matter what value is set as the current
|
no matter what value is set as the current
|
||||||
.Cm Q
|
.Cm Q
|
||||||
option.
|
option.
|
||||||
|
.Nm
|
||||||
|
.Em does not check precisions for consistency ,
|
||||||
|
so nonsensical input like
|
||||||
|
.Ql MUL(4.2q8, 6.9q12, 16)
|
||||||
|
will produce a nonsensical (but technically correct) result:
|
||||||
|
.Dq garbage in, garbage out .
|
||||||
.Pp
|
.Pp
|
||||||
The
|
The
|
||||||
.Ic FMOD
|
.Ic FMOD
|
||||||
@@ -439,21 +465,26 @@ this is the opposite of how the integer modulo operator
|
|||||||
.Sq %
|
.Sq %
|
||||||
works!
|
works!
|
||||||
.Pp
|
.Pp
|
||||||
The trigonometry functions (
|
The trigonometry functions
|
||||||
.Ic SIN ,
|
.Pq Ic SIN , Ic COS , Ic TAN , No etc
|
||||||
.Ic COS ,
|
are defined in terms of a circle divided into 1.0
|
||||||
.Ic TAN ,
|
.Dq turns
|
||||||
etc) are defined in terms of a circle divided into 1.0 "turns" (equal to 2pi radians or 360 degrees).
|
.EQ
|
||||||
|
delim $$
|
||||||
|
.EN
|
||||||
|
(equal to $2 pi$ radians, or 360 degrees).
|
||||||
|
.EQ
|
||||||
|
delim off
|
||||||
|
.EN
|
||||||
.Pp
|
.Pp
|
||||||
These functions are useful for automatic generation of various tables.
|
These functions are useful for automatic generation of various tables.
|
||||||
For example:
|
For example:
|
||||||
.Bd -literal -offset indent
|
.Bd -literal -offset indent
|
||||||
; Generate a table of sine values from sin(0.0) to sin(1.0), with
|
; Generate a table of 128 sine values
|
||||||
; amplitude scaled from [-1.0, 1.0] to [0.0, 128.0]
|
; from sin(0.0) to sin(0.5) excluded,
|
||||||
DEF turns = 0.0
|
; with amplitude scaled from [-1.0, 1.0] to [0.0, 128.0].
|
||||||
REPT 256
|
FOR angle, 0.0, 0.5, 0.5 / 128
|
||||||
db MUL(64.0, SIN(turns) + 1.0) >> 16
|
db MUL(SIN(angle) + 1.0, 128.0 / 2) >> 16
|
||||||
DEF turns += 1.0 / 256
|
|
||||||
ENDR
|
ENDR
|
||||||
.Ed
|
.Ed
|
||||||
.Ss String expressions
|
.Ss String expressions
|
||||||
|
|||||||
Reference in New Issue
Block a user