diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..b753b591 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,11 @@ +# Style guide + +This outlines recommended practices for contributors to this package. + +## Naming + +- Type parameters: use `F` for `F <: Fixed`, `N` for `N <: Normed`, + and `X` for `X <: FixedPoint`. Use `f` for the number of fractional bits. +- Use `Ti` for `Ti <: Integer`, `Tf` for `Tf <: AbstractFloat`, and `Tw` + for `widen`ed types. +- `T` should refer to the underlying "raw" type. diff --git a/README.md b/README.md index dd0d086d..464c1018 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![codecov.io](http://codecov.io/github/JuliaMath/FixedPointNumbers.jl/coverage.svg?branch=master)](http://codecov.io/github/JuliaMath/FixedPointNumbers.jl?branch=master) This library implements fixed-point number types. A -[fixed-point number][wikipedia] represents a fractional, or +[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 @@ -37,7 +37,7 @@ 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 -``` +```julia -1.0 = -128/128 ≤ x ≤ 127/128 ≈ 0.992. ``` @@ -64,4 +64,82 @@ 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}`. -[wikipedia]: http://en.wikipedia.org/wiki/Fixed-point_arithmetic +# Computation with Fixed and Normed numbers + +You can perform mathematical operations with `FixedPoint` numbers, but keep in mind +that they are vulnerable to both [rounding] and [overflow]. For example: + +```julia +julia> x = N0f8(0.8) +0.8N0f8 + +julia> float(x) + x +1.6f0 + +julia> x + x +0.596N0f8 +``` + +This is a consequence of the rules that govern overflow in integer arithmetic: + +```julia +julia> y = reinterpret(x) # `reinterpret(x::FixedPoint)` reinterprets as the underlying "raw" type +0xcc + +julia> reinterpret(N0f8, y + y) # add two UInt8s and then reinterpret as N0f8 +0.596N0f8 +``` + +Similarly, + +```julia +julia> x = eps(N0f8) # smallest nonzero `N0f8` number +0.004N0f8 + +julia> x*x +0.0N0f8 +``` + +which is rounding-induced [underflow]. Finally, + +```julia +julia> x = N4f12(15) +15.0N4f12 + +julia> x*x +ERROR: ArgumentError: Normed{UInt16,12} is a 16-bit type representing 65536 values from 0.0 to 16.0037; cannot represent 225.0 +Stacktrace: + [1] throw_converterror(::Type{Normed{UInt16,12}}, ::Float32) at /home/tim/.julia/dev/FixedPointNumbers/src/FixedPointNumbers.jl:251 + [2] _convert at /home/tim/.julia/dev/FixedPointNumbers/src/normed.jl:77 [inlined] + [3] FixedPoint at /home/tim/.julia/dev/FixedPointNumbers/src/FixedPointNumbers.jl:51 [inlined] + [4] convert at ./number.jl:7 [inlined] + [5] *(::Normed{UInt16,12}, ::Normed{UInt16,12}) at /home/tim/.julia/dev/FixedPointNumbers/src/normed.jl:254 + [6] top-level scope at REPL[16]:1 +``` + +In some circumstances, it may make most sense to think of `FixedPoint` numbers as *storage types* +rather than computational types. You can call `float(x)` to convert `x` to a floating-point equivalent that is reasonably +safe for computation; in the type domain, `floattype(T::Type)` returns the corresponding type. +Note that in some cases `floattype(T)` differs from `float`'s behavior on the corresponding "raw" type: + +```julia +julia> float(UInt8) +Float64 + +julia> floattype(N0f8) +Float32 +``` + +Because of the role of FixedPointNumbers in domains such as image-processing, this package tries to limit the expansion of the +number of bits needed to store results. + + +## Contributing to this package + +Please see [CONTRIBUTING.md](CONTRIBUTING.md) for information about improving this package. + + +[fixed-point number]: http://en.wikipedia.org/wiki/Fixed-point_arithmetic +[overflow]: https://en.wikipedia.org/wiki/Integer_overflow +[rounding]: https://en.wikipedia.org/wiki/Round-off_error +[underflow]: https://en.wikipedia.org/wiki/Arithmetic_underflow