diff --git a/man/rgbasm.5 b/man/rgbasm.5 index a3b5c9511..7834e531e 100644 --- a/man/rgbasm.5 +++ b/man/rgbasm.5 @@ -369,23 +369,28 @@ equals $roman clz ( n )$. delim off .EN .Ss Fixed-point expressions -Fixed-point numbers are basically normal (32-bit) integers, which count fractions instead of whole numbers. -They offer better precision than integers but limit the range of values. -By default, the upper 16 bits are used for the integer part and the lower 16 bits are used for the fraction (65536ths). -The default number of fractional bits can be changed with the +Fixed-point numbers are technically just integers, but conceptually they have a decimal point at a fixed location (hence the name). +This gives them increased precision, at the cost of a smaller range, while remaining far cheaper to manipulate than floating-point numbers (which +.Nm +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 -command-line option. -You can also specify a precise fixed-point value by appending a +command-line option, and/or by +.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 -to it followed by the number of fractional bits, such as -.Ql 12.34q8 . +followed by the number of fractional bits: for example, +.Ql 1234.5q8 +is equal to $0004d2_80 +.EQ +delim $$ +.EN +($= 1234.5 * 2 sup 8$). .Pp 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. It follows that you can convert an integer to a fixed-point number by shifting it left that same amount. .Pp @@ -393,19 +398,16 @@ Note that the current number of fractional bits can be computed as .Ic TZCOUNT Ns Pq 1.0 . .Pp The following functions are designed to operate with fixed-point numbers: -.EQ -delim $$ -.EN .Bl -column -offset indent "ATAN2(y, x)" .It Sy Name Ta Sy Operation -.It Fn DIV x y Ta Fixed-point division $( x \[di] y ) \[mu] ( 2 ^ precision )$ -.It Fn MUL x y Ta Fixed-point multiplication $( x \[mu] y ) \[di] ( 2 ^ precision )$ -.It Fn FMOD x y Ta Fixed-point modulo $( x % y ) \[di] ( 2 ^ precision )$ -.It Fn POW x y Ta $x$ to the $y$ power +.It Fn DIV x y Ta Fixed-point division +.It Fn MUL x y Ta Fixed-point multiplication +.It Fn FMOD x y Ta Fixed-point modulo +.It Fn POW x y Ta $x sup 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 CEIL x Ta Round $x$ up to an integer -.It Fn FLOOR x Ta Round $x$ down to an integer +.It Fn CEIL x Ta Round $x$ up to the nearest integer +.It Fn FLOOR x Ta Round $x$ down to the nearest integer .It Fn SIN x Ta Sine of $x$ .It Fn COS x Ta Cosine of $x$ .It Fn TAN x Ta Tangent of $x$ @@ -418,7 +420,25 @@ delim $$ delim off .EN .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, .Ql MUL(6.0q8, 7.0q8, 8) will evaluate to @@ -426,6 +446,12 @@ will evaluate to no matter what value is set as the current .Cm Q 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 The .Ic FMOD @@ -439,21 +465,26 @@ this is the opposite of how the integer modulo operator .Sq % works! .Pp -The trigonometry functions ( -.Ic SIN , -.Ic COS , -.Ic TAN , -etc) are defined in terms of a circle divided into 1.0 "turns" (equal to 2pi radians or 360 degrees). +The trigonometry functions +.Pq Ic SIN , Ic COS , Ic TAN , No etc +are defined in terms of a circle divided into 1.0 +.Dq turns +.EQ +delim $$ +.EN +(equal to $2 pi$ radians, or 360 degrees). +.EQ +delim off +.EN .Pp These functions are useful for automatic generation of various tables. For example: .Bd -literal -offset indent -; Generate a table of sine values from sin(0.0) to sin(1.0), with -; amplitude scaled from [-1.0, 1.0] to [0.0, 128.0] -DEF turns = 0.0 -REPT 256 - db MUL(64.0, SIN(turns) + 1.0) >> 16 - DEF turns += 1.0 / 256 +; Generate a table of 128 sine values +; from sin(0.0) to sin(0.5) excluded, +; with amplitude scaled from [-1.0, 1.0] to [0.0, 128.0]. +FOR angle, 0.0, 0.5, 0.5 / 128 + db MUL(SIN(angle) + 1.0, 128.0 / 2) >> 16 ENDR .Ed .Ss String expressions