20

14

24

23

# FixedPointNumbers  This library implements fixed-point number types. A fixed-point number represents a fractional, or non-integral, number. In contrast with the more widely known floating-point numbers, with fixed-point numbers the decimal point doesn't "float": fixed-point numbers are effectively integers that are interpreted as being scaled by a constant factor. Consequently, they have a fixed number of digits (bits) after the decimal (radix) point.

Fixed-point numbers can be used to perform arithmetic. Another practical application is to implicitly rescale integers without modifying the underlying representation.

This library exports two categories of fixed-point types. Fixed-point types are used like any other number: they can be added, multiplied, raised to a power, etc. In some cases these operations result in conversion to floating-point types.

# Type hierarchy and interpretation

This library defines an abstract type `FixedPoint{T <: Integer, f}` as a subtype of `Real`. The parameter `T` is the underlying machine representation and `f` is the number of fraction bits.

For `T<:Signed` (a signed integer), there is a fixed-point type `Fixed{T, f}`; for `T<:Unsigned` (an unsigned integer), there is the `Normed{T, f}` type. However, there are slight differences in behavior that go beyond signed/unsigned distinctions.

The `Fixed{T,f}` types use 1 bit for sign, and `f` bits to represent the fraction. For example, `Fixed{Int8,7}` uses 7 bits (all bits except the sign bit) for the fractional part. The value of the number is interpreted as if the integer representation has been divided by `2^f`. Consequently, `Fixed{Int8,7}` numbers `x` satisfy

``````-1.0 = -128/128 ≤ x ≤ 127/128 ≈ 0.992.
``````

because the range of `Int8` is from -128 to 127.

In contrast, the `Normed{T,f}`, with `f` fraction bits, map the closed interval [0.0,1.0] to the span of numbers with `f` bits. For example, the `N0f8` type (aliased to `Normed{UInt8,8}`) is represented internally by a `UInt8`, and makes `0x00` equivalent to `0.0` and `0xff` to `1.0`. Consequently, `Normed` numbers are scaled by `2^f-1` rather than `2^f`. The type aliases `N6f10`, `N4f12`, `N2f14`, and `N0f16` are all based on `UInt16` and reach the value `1.0` at 10, 12, 14, and 16 bits, respectively (`0x03ff`, `0x0fff`, `0x3fff`, and `0xffff`). The `NXfY` notation is used for compact printing and the `fY` component informs about the number of fractional bits and `X+Y` equals the number of underlying bits used.

To construct such a number, use `convert(N4f12, 1.3)`, `N4f12(1.3)`, `Normed{UInt16,12}(1.3)`, or `reinterpret(N4f12, 0x14cc)`. The latter syntax means to construct a `N4f12` (it ends in `uf12`) from the `UInt16` value `0x14cc`.

More generally, an arbitrary number of bits from any of the standard unsigned integer widths can be used for the fractional part. For example: `Normed{UInt32,16}`, `Normed{UInt64,3}`, `Normed{UInt128,7}`.

02/27/2014

5 days ago

221 commits