2019-03-15 15:23:47 +01:00
|
|
|
# Working With Floating Point
|
|
|
|
|
|
|
|
Some RETRO systems include support for floating point numbers.
|
|
|
|
When present, this is built over the system `libm` using the
|
|
|
|
C `double` type.
|
|
|
|
|
|
|
|
Floating point values are typically 64 bit IEEE 754 double
|
|
|
|
precision (1 bit for the sign, 11 bits for the exponent, and
|
|
|
|
the remaining 52 bits for the value), i.e. 15 decimal digits
|
|
|
|
of precision.
|
|
|
|
|
2021-03-30 13:58:25 +02:00
|
|
|
## Sigil
|
2019-03-15 15:23:47 +01:00
|
|
|
|
|
|
|
Floating point numbers start with a `.`
|
|
|
|
|
|
|
|
Examples:
|
|
|
|
|
|
|
|
Token Value
|
|
|
|
.1 1.0
|
|
|
|
.0.5 0.5
|
|
|
|
.-.4 -0.4
|
|
|
|
.1.3 1.3
|
2019-03-19 19:53:12 +01:00
|
|
|
|
|
|
|
## Namespace
|
|
|
|
|
|
|
|
Floating point words are in the `f:` namespace. There is also
|
|
|
|
a related `e:` namespace for *encoded values*, which allows
|
|
|
|
storing of floats in standard memory.
|
|
|
|
|
|
|
|
## Operation
|
|
|
|
|
|
|
|
Floating point values exist on a separate stack, and are bigger
|
|
|
|
than the standard memory cells, so can not be directly stored
|
|
|
|
and fetched from memory.
|
|
|
|
|
|
|
|
The floating point system also provides an alternate stack that
|
|
|
|
can be used to temporarily store values.
|
|
|
|
|
2019-03-19 20:16:02 +01:00
|
|
|
The following words exist for arranging values on the floating
|
|
|
|
point stack. These are direct analogs to the non-prefiexd words
|
|
|
|
for dealing with the data stack.
|
|
|
|
|
|
|
|
- `f:nip`
|
|
|
|
- `f:over`
|
|
|
|
- `f:depth`
|
|
|
|
- `f:drop`
|
|
|
|
- `f:drop-pair`
|
|
|
|
- `f:dup`
|
|
|
|
- `f:dup-pair`
|
|
|
|
- `f:dump-stack`
|
|
|
|
- `f:tuck`
|
|
|
|
- `f:swap`
|
|
|
|
- `f:rot`
|
|
|
|
|
|
|
|
For the secondary floating point stack, the following words are
|
|
|
|
provided:
|
|
|
|
|
|
|
|
- `f:push`
|
|
|
|
- `f:pop`
|
|
|
|
- `f:adepth`
|
|
|
|
- `f:dump-astack`
|
|
|
|
|
|
|
|
## Constants
|
|
|
|
|
|
|
|
| Name | Returns |
|
|
|
|
| -------- | ----------------- |
|
|
|
|
| `f:E` | Euler's number |
|
|
|
|
| `f:-INF` | Negative infinity |
|
|
|
|
| `f:INF` | Positive infinity |
|
|
|
|
| `f:NAN` | Not a Number |
|
|
|
|
| `f:PI` | PI |
|
|
|
|
|
|
|
|
## Comparisons
|
|
|
|
|
|
|
|
The basic set of comparators are the same as those for
|
|
|
|
operating on integers. These are:
|
|
|
|
|
|
|
|
- `f:-eq?`
|
|
|
|
- `f:between?`
|
|
|
|
- `f:eq?`
|
|
|
|
- `f:gt?`
|
|
|
|
- `f:lt?`
|
|
|
|
- `f:negative?`
|
|
|
|
- `f:positive?`
|
|
|
|
- `f:case`
|
|
|
|
|
|
|
|
There are also a few additions for comparing to special values
|
|
|
|
like infinity and NaN.
|
|
|
|
|
|
|
|
- `f:-inf?`
|
|
|
|
- `f:inf?`
|
|
|
|
- `f:nan?`
|
|
|
|
|
|
|
|
## Basic Math
|
|
|
|
|
|
|
|
- `f:*`
|
|
|
|
- `f:+`
|
|
|
|
- `f:-`
|
|
|
|
- `f:/`
|
|
|
|
- `f:abs`
|
|
|
|
- `f:floor`
|
|
|
|
- `f:inc`
|
|
|
|
- `f:limit`
|
|
|
|
- `f:max`
|
|
|
|
- `f:min`
|
|
|
|
- `f:negate`
|
|
|
|
- `f:power`
|
|
|
|
- `f:ceiling`
|
|
|
|
- `f:dec`
|
|
|
|
- `f:log`
|
|
|
|
- `f:sqrt`
|
|
|
|
- `f:square`
|
|
|
|
- `f:round`
|
|
|
|
- `f:sign`
|
|
|
|
- `f:signed-sqrt`
|
|
|
|
- `f:signed-square`
|
|
|
|
|
|
|
|
## Geometry
|
|
|
|
|
2019-03-19 21:11:23 +01:00
|
|
|
RETRO provides a small number of words for doing geometric
|
|
|
|
related calculations.
|
|
|
|
|
|
|
|
| Word | Returns |
|
|
|
|
| -------- | ------------ |
|
|
|
|
| `f:acos` | arc cosine |
|
|
|
|
| `f:asin` | arc sine |
|
|
|
|
| `f:atan` | arc tangent |
|
|
|
|
| `f:cos` | cosine |
|
|
|
|
| `f:sin` | sine |
|
|
|
|
| `f:tan` | tangent |
|
2019-03-19 20:16:02 +01:00
|
|
|
|
|
|
|
## Storage and Retrieval
|
|
|
|
|
2019-03-19 21:11:23 +01:00
|
|
|
By leveraging the encoded value functions, RETRO is able to
|
|
|
|
allow storage of floating point values in memory. This does
|
|
|
|
have a tradeoff in accuracy as the memory cells are considerably
|
|
|
|
smaller than a full floating point size.
|
|
|
|
|
|
|
|
You can use `f:fetch` to fetch a floating point value and
|
|
|
|
`f:store` to store one.
|
|
|
|
|
|
|
|
If you need more precision, try Kiyoshi Yoneda's FloatVar
|
|
|
|
example (`example/FloatVar.forth`), which includes words to
|
|
|
|
store and retrieve values using multiple cells.
|
|
|
|
|
2019-03-19 20:16:02 +01:00
|
|
|
- `f:to-number`
|
|
|
|
- `f:to-string`
|
|
|
|
|
|
|
|
## I/O
|
|
|
|
|
2019-03-19 21:11:23 +01:00
|
|
|
The floating point vocabulary has a single I/O word, `f:put`,
|
|
|
|
for the display of floating point numbers.
|
2019-03-19 19:53:12 +01:00
|
|
|
|
|
|
|
## Encoded Values
|
|
|
|
|
|
|
|
RETRO provides a means of encoding and decoding floating point
|
|
|
|
values into standard integer cells. This is based on the paper
|
|
|
|
"Encoding floating point values to shorter integers" by Kiyoshi
|
|
|
|
Yoneda and Charles Childers.
|
2019-03-19 20:16:02 +01:00
|
|
|
|
|
|
|
- `f:E1`
|
|
|
|
- `f:to-e`
|
|
|
|
- `e:-INF`
|
|
|
|
- `e:-inf?`
|
|
|
|
- `e:INF`
|
|
|
|
- `e:MAX`
|
|
|
|
- `e:MIN`
|
|
|
|
- `e:NAN`
|
|
|
|
- `e:clip`
|
|
|
|
- `e:inf?`
|
|
|
|
- `e:max?`
|
|
|
|
- `e:min?`
|
|
|
|
- `e:n?`
|
|
|
|
- `e:nan?`
|
|
|
|
- `e:put`
|
|
|
|
- `e:to-f`
|
|
|
|
- `e:zero?`
|