Fixed-Width Arithmetic
Fixed-width arithmetic is a form of integer arithmetic where rational numbers are scaled to a whole-number value, with an implied "decimal point".
Percentages are an example of this, e.g. 5 percent is a whole-number
representation of 0.05. In this case, the scale is 100
Additional precision is possible by scaling to higher numbers -- scaling to
10000 gives 4 decimal points of precision.
One may also scale to non-decimal values, for example, 214.
Rather than decimal points of precision, gives 14 bits of fractional precision. For
an unsigned 32 bit integer, this means any value from [0 - 16383] represents
a scaled number between 0 and 1, with a "1" value of 16384. The largest
unscaled value that may be represented is 232-18 = 218 = 262144.
bit-wise layout of a 32-bit unsigned integer, scaled to 14 bits of precision. whole-number bits...... . fractional bits. 0000 0000 0000 0000 001 . 0 0000 0000 0000
Examples
The following is a Modal program that calculates the average interest rate of 3 loans, to 4 decimal points of precision.
This example defines the scale (*/) operator, which takes three
arguments on a stack: numerator, denominator, and scalar. The operator first
multiplies the numerator by the scalar, then applies the denominator -- resulting
in a scaled fixed-width number.
(this example also illustrates how to simulate forth in modal)
<> (:: ?x) () :: comment <> ($> lit ?x) (?x $>) :: literal <> (?y ?x $> concat) (?(?^ ?^) (?y ?x) $> ) <> ($> .) (#print $>) <> (?: #print) (?:) :: (stack operators) <> (?x ?y $> swap) (?y ?x $>) <> (?x $> dup) (?x ?x $>) <> (?a ?b ?c $> swapd) (?b ?a ?c $>) <> (?a ?b ?c $> rotate) (?c ?b ?a $>) <> (?a ?b ?c $> rollup) (?c ?a ?b $>) <> (?a ?b ?c $> rolldown) (?b ?c ?a $>) :: (math coprocessor) <> (?1 ?0 $> `?:) (?: $>) :: (arithmetic on 2 terms) <> (?2 ?1 ?0 $> ``?:) (?: $>) :: (arithmetic on 3 terms) :: (Step 1: Multiply each loan balance by the corresponding interest rate ) :: (Step 2: Add the products together) :: (Step 3: Divide the sum by the total debt) <> (*/) (rollup `* `/) :: (scale operator: n1 n2 n3 -- n) <> (^1) (lit 16834) :: (fixed-width scalar, 2^14) <> (*.) (^1 */) :: (scaled multiply) <> (/.) (^1 swap */) :: (scaled division) :: (get the average interest rate of 3 loans: $8710 at .0365 (3.65%) $3948 at .0438 (4.38%) $9810 at .0517 (5.17%)) $> lit 365 lit 10000 /. lit 8710 `* lit 438 lit 10000 /. lit 3948 `* lit 517 lit 10000 /. lit 9810 `* ``+ lit 8710 lit 3948 lit 9810 ``+ swap `/ lit 10000 *. lit .0 swap concat . Completed in 89 rewrites. .0443