Skip to content

Commit 817dcfd

Browse files
authored
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
1 parent a3f9952 commit 817dcfd

File tree

1 file changed

+65
-34
lines changed

1 file changed

+65
-34
lines changed

man/rgbasm.5

+65-34
Original file line numberDiff line numberDiff line change
@@ -369,43 +369,45 @@ equals $roman clz ( n )$.
369369
delim off
370370
.EN
371371
.Ss Fixed-point expressions
372-
Fixed-point numbers are basically normal (32-bit) integers, which count fractions instead of whole numbers.
373-
They offer better precision than integers but limit the range of values.
374-
By default, the upper 16 bits are used for the integer part and the lower 16 bits are used for the fraction (65536ths).
375-
The default number of fractional bits can be changed with the
372+
Fixed-point numbers are technically just integers, but conceptually they have a decimal point at a fixed location (hence the name).
373+
This gives them increased precision, at the cost of a smaller range, while remaining far cheaper to manipulate than floating-point numbers (which
374+
.Nm
375+
does not support).
376+
.Pp
377+
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.
378+
This precision can be changed with the
376379
.Fl Q
377-
command-line option.
378-
You can also specify a precise fixed-point value by appending a
380+
command-line option, and/or by
381+
.Ic OPT Q
382+
.Pq see Sx Changing options while assembling .
383+
An individual fixed-point literal can specify its own precision, overriding the current default, by appending a
379384
.Dq q
380-
to it followed by the number of fractional bits, such as
381-
.Ql 12.34q8 .
385+
followed by the number of fractional bits: for example,
386+
.Ql 1234.5q8
387+
is equal to $0004d2_80
388+
.EQ
389+
delim $$
390+
.EN
391+
($= 1234.5 * 2 sup 8$).
382392
.Pp
383393
Since fixed-point values are still just integers, you can use them in normal integer expressions.
384-
Some integer operators like
385-
.Sq +
386-
and
387-
.Sq -
388-
don't care whether the operands are integers or fixed-point.
389394
You can easily truncate a fixed-point number into an integer by shifting it right by the number of fractional bits.
390395
It follows that you can convert an integer to a fixed-point number by shifting it left that same amount.
391396
.Pp
392397
Note that the current number of fractional bits can be computed as
393398
.Ic TZCOUNT Ns Pq 1.0 .
394399
.Pp
395400
The following functions are designed to operate with fixed-point numbers:
396-
.EQ
397-
delim $$
398-
.EN
399401
.Bl -column -offset indent "ATAN2(y, x)"
400402
.It Sy Name Ta Sy Operation
401-
.It Fn DIV x y Ta Fixed-point division $( x \[di] y ) \[mu] ( 2 ^ precision )$
402-
.It Fn MUL x y Ta Fixed-point multiplication $( x \[mu] y ) \[di] ( 2 ^ precision )$
403-
.It Fn FMOD x y Ta Fixed-point modulo $( x % y ) \[di] ( 2 ^ precision )$
404-
.It Fn POW x y Ta $x$ to the $y$ power
403+
.It Fn DIV x y Ta Fixed-point division
404+
.It Fn MUL x y Ta Fixed-point multiplication
405+
.It Fn FMOD x y Ta Fixed-point modulo
406+
.It Fn POW x y Ta $x sup y$
405407
.It Fn LOG x y Ta Logarithm of $x$ to the base $y$
406408
.It Fn ROUND x Ta Round $x$ to the nearest integer
407-
.It Fn CEIL x Ta Round $x$ up to an integer
408-
.It Fn FLOOR x Ta Round $x$ down to an integer
409+
.It Fn CEIL x Ta Round $x$ up to the nearest integer
410+
.It Fn FLOOR x Ta Round $x$ down to the nearest integer
409411
.It Fn SIN x Ta Sine of $x$
410412
.It Fn COS x Ta Cosine of $x$
411413
.It Fn TAN x Ta Tangent of $x$
@@ -418,14 +420,38 @@ delim $$
418420
delim off
419421
.EN
420422
.Pp
421-
All of these fixed-point functions can take an optional final argument, which is the precision to use.
423+
There are no functions for fixed-point addition and subtraction, because the
424+
.Sq +
425+
and
426+
.Sq -
427+
operators can add and subtract pairs of fixed-point operands.
428+
.Bd -ragged -offset indent
429+
Note that some operators or functions are meaningful when combining integers and fixed-point values.
430+
For example,
431+
.Ql 2.0 * 3
432+
is equivalent to
433+
.Ql MUL(2.0, 3.0) ,
434+
and
435+
.Ql 6.0 / 2
436+
is equivalent to
437+
.Ql DIV(6.0, 2.0) .
438+
Be careful and think about what the operations mean when doing this sort of thing.
439+
.Ed
440+
.Pp
441+
All of these fixed-point functions can take an optional final argument, which is the precision to use for that one operation.
422442
For example,
423443
.Ql MUL(6.0q8, 7.0q8, 8)
424444
will evaluate to
425445
.Ql 42.0q8
426446
no matter what value is set as the current
427447
.Cm Q
428448
option.
449+
.Nm
450+
.Em does not check precisions for consistency ,
451+
so nonsensical input like
452+
.Ql MUL(4.2q8, 6.9q12, 16)
453+
will produce a nonsensical (but technically correct) result:
454+
.Dq garbage in, garbage out .
429455
.Pp
430456
The
431457
.Ic FMOD
@@ -439,21 +465,26 @@ this is the opposite of how the integer modulo operator
439465
.Sq %
440466
works!
441467
.Pp
442-
The trigonometry functions (
443-
.Ic SIN ,
444-
.Ic COS ,
445-
.Ic TAN ,
446-
etc) are defined in terms of a circle divided into 1.0 "turns" (equal to 2pi radians or 360 degrees).
468+
The trigonometry functions
469+
.Pq Ic SIN , Ic COS , Ic TAN , No etc
470+
are defined in terms of a circle divided into 1.0
471+
.Dq turns
472+
.EQ
473+
delim $$
474+
.EN
475+
(equal to $2 pi$ radians, or 360 degrees).
476+
.EQ
477+
delim off
478+
.EN
447479
.Pp
448480
These functions are useful for automatic generation of various tables.
449481
For example:
450482
.Bd -literal -offset indent
451-
; Generate a table of sine values from sin(0.0) to sin(1.0), with
452-
; amplitude scaled from [-1.0, 1.0] to [0.0, 128.0]
453-
DEF turns = 0.0
454-
REPT 256
455-
db MUL(64.0, SIN(turns) + 1.0) >> 16
456-
DEF turns += 1.0 / 256
483+
; Generate a table of 128 sine values
484+
; from sin(0.0) to sin(0.5) excluded,
485+
; with amplitude scaled from [-1.0, 1.0] to [0.0, 128.0].
486+
FOR angle, 0.0, 0.5, 0.5 / 128
487+
db MUL(SIN(angle) + 1.0, 128.0 / 2) >> 16
457488
ENDR
458489
.Ed
459490
.Ss String expressions

0 commit comments

Comments
 (0)