Skip to content

Commit 4c30ba6

Browse files
committed
Merge pull request #27 from vchuravy/vc/design_rework
[RFC/WIP] Homogenise design
2 parents bb3dee7 + 2a4bc3c commit 4c30ba6

File tree

12 files changed

+311
-280
lines changed

12 files changed

+311
-280
lines changed

.travis.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@ os:
33
- linux
44
- osx
55
julia:
6-
- 0.3
76
- 0.4
87
- nightly
98
notifications:
109
email: false
10+
script:
11+
- if [[ -a .git/shallow ]]; then git fetch --unshallow; fi
12+
- julia -e 'Pkg.clone(pwd()); Pkg.build("FixedPointNumbers")'
13+
- julia -e 'cd(Pkg.dir("FixedPointNumbers", "test")); include("runtests.jl")'

README.md

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,28 +14,23 @@ This library exports two categories of fixed-point types. Fixed-point types are
1414
used like any other number: they can be added, multiplied, raised to a power,
1515
etc. In many cases these operations result in conversion to floating-point types.
1616

17-
## Fixed32 (signed fixed-point numbers)
17+
# Type hierarchy
18+
This library defines an abstract type `FixedPoint{T <: Integer, f}` as a subtype of `Real`. The parameter `T` is the underlying representation and `f` is the number of fraction bits.
1819

19-
For signed integers, there is a 32-bit fixed-point type `Fixed32{f}`.
20-
The parameter `f` is the number of fraction bits. There is also an abstract subtype of
21-
`Real` called `Fixed`.
20+
For signed integers, there is a fixed-point type `Fixed{T, f}` and for unsigned integers, there is the `UFixed{T, f}` type.
2221

23-
To use it, convert numbers to a `Fixed32` type, or call `Fixed32(x)`, which will default
24-
to constructing a `Fixed32{16}`.
25-
26-
## Ufixed (unsigned fixed-point numbers)
27-
28-
For unsigned integers, there is a family of subtypes of the abstract `Ufixed` type.
2922
These types, built with `f` fraction bits, map the closed interval [0.0,1.0]
3023
to the span of numbers with `f` bits.
31-
For example, the `Ufixed8` type is represented internally by a `Uint8`, and makes
24+
For example, the `UFixed8` type is represented internally by a `UInt8`, and makes
3225
`0x00` equivalent to `0.0` and `0xff` to `1.0`.
33-
The types `Ufixed10`, `Ufixed12`, `Ufixed14`, and `Ufixed16` are all based on `Uint16`
26+
The types `UFixed10`, `UFixed12`, `UFixed14`, and `UFixed16` are all based on `UInt16`
3427
and reach the value `1.0` at 10, 12, 14, and 16 bits, respectively (`0x03ff`, `0x0fff`,
3528
`0x3fff`, and `0xffff`).
3629

37-
To construct such a number, use `convert(Ufixed12, 1.3)`, `ufixed12(1.3)`, or the literal syntax `0x14ccuf12`.
38-
The latter syntax means to construct a `Ufixed12` (it ends in `uf12`) from the `Uint16` value
30+
To construct such a number, use `convert(UFixed12, 1.3)`, `ufixed12(1.3)`, or the literal syntax `0x14ccuf12`.
31+
The latter syntax means to construct a `UFixed12` (it ends in `uf12`) from the `UInt16` value
3932
`0x14cc`.
4033

34+
There currently is no literal syntax for signed `Fixed` numbers.
35+
4136
[wikipedia]: http://en.wikipedia.org/wiki/Fixed-point_arithmetic

REQUIRE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
julia 0.3
1+
julia 0.4-
22
Compat 0.2.2

src/FixedPointNumbers.jl

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,20 @@ import Base: ==, <, <=, -, +, *, /, ~,
1111
trunc, round, floor, ceil, bswap,
1212
div, fld, rem, mod, mod1, rem1, fld1, min, max,
1313
start, next, done
14-
15-
abstract FixedPoint <: Real
16-
abstract Fixed <: FixedPoint
17-
abstract Ufixed <: FixedPoint # unsigned variant
14+
# T => BaseType
15+
# f => Number of Bytes reserved for fractional part
16+
abstract FixedPoint{T <: Integer, f} <: Real
1817

1918
export
2019
FixedPoint,
2120
Fixed,
22-
Ufixed,
23-
Fixed32,
24-
Ufixed8,
25-
Ufixed10,
26-
Ufixed12,
27-
Ufixed14,
28-
Ufixed16,
21+
UFixed,
22+
Fixed16,
23+
UFixed8,
24+
UFixed10,
25+
UFixed12,
26+
UFixed14,
27+
UFixed16,
2928
# constructors
3029
ufixed8,
3130
ufixed10,
@@ -43,10 +42,26 @@ export
4342

4443
reinterpret(x::FixedPoint) = x.i
4544

46-
include("fixed32.jl")
45+
# comparison
46+
=={T <: FixedPoint}(x::T, y::T) = x.i == y.i
47+
<{T <: FixedPoint}(x::T, y::T) = x.i < y.i
48+
<={T <: FixedPoint}(x::T, y::T) = x.i <= y.i
49+
50+
# predicates
51+
isinteger{T,f}(x::FixedPoint{T,f}) = (x.i&(1<<f-1)) == 0
52+
53+
typemax{T<: FixedPoint}(::Type{T}) = T(typemax(rawtype(T)), 0)
54+
typemin{T<: FixedPoint}(::Type{T}) = T(typemin(rawtype(T)), 0)
55+
realmin{T<: FixedPoint}(::Type{T}) = typemin(T)
56+
realmax{T<: FixedPoint}(::Type{T}) = typemax(T)
57+
58+
include("fixed.jl")
4759
include("ufixed.jl")
60+
include("deprecations.jl")
61+
4862

49-
for T in tuple(Fixed32, UF...)
63+
# TODO: rewrite this by @generated
64+
for T in tuple(Fixed16, UF...)
5065
R = rawtype(T)
5166
@eval begin
5267
reinterpret(::Type{$R}, x::$T) = x.i

src/deprecations.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import Base.@deprecate_binding
2+
3+
@deprecate_binding UfixedBase UFixed
4+
@deprecate_binding UfixedConstructor UFixedConstructor
5+
@deprecate_binding Ufixed UFixed
6+
@deprecate_binding Ufixed8 UFixed8
7+
@deprecate_binding Ufixed10 UFixed10
8+
@deprecate_binding Ufixed12 UFixed12
9+
@deprecate_binding Ufixed14 UFixed14
10+
@deprecate_binding Ufixed16 UFixed16
11+
12+
@deprecate_binding Fixed32 Fixed16
13+
@deprecate Fixed(x::Real) convert(Fixed{Int32, 16}, x)

src/fixed.jl

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# 32-bit fixed point; parameter `f` is the number of fraction bits
2+
immutable Fixed{T <: Signed,f} <: FixedPoint{T, f}
3+
i::T
4+
5+
# constructor for manipulating the representation;
6+
# selected by passing an extra dummy argument
7+
Fixed(i::Integer,_) = new(i % T)
8+
9+
Fixed(x) = convert(Fixed{T,f}, x)
10+
end
11+
12+
typealias Fixed16 Fixed{Int32, 16}
13+
14+
rawtype{T,f}(::Type{Fixed{T,f}}) = T
15+
nbitsfrac{T,f}(::Type{Fixed{T,f}}) = f
16+
17+
# basic operators
18+
-{T,f}(x::Fixed{T,f}) = Fixed{T,f}(-x.i,0)
19+
abs{T,f}(x::Fixed{T,f}) = Fixed{T,f}(abs(x.i),0)
20+
21+
+{T,f}(x::Fixed{T,f}, y::Fixed{T,f}) = Fixed{T,f}(x.i+y.i,0)
22+
-{T,f}(x::Fixed{T,f}, y::Fixed{T,f}) = Fixed{T,f}(x.i-y.i,0)
23+
24+
# with truncation:
25+
#*{f}(x::Fixed32{f}, y::Fixed32{f}) = Fixed32{f}(Base.widemul(x.i,y.i)>>f,0)
26+
# with rounding up:
27+
*{T,f}(x::Fixed{T,f}, y::Fixed{T,f}) = Fixed{T,f}((Base.widemul(x.i,y.i) + (convert(widen(T), 1) << (f-1) ))>>f,0)
28+
29+
/{T,f}(x::Fixed{T,f}, y::Fixed{T,f}) = Fixed{T,f}(div(convert(widen(T), x.i) << f, y.i), 0)
30+
31+
32+
# # conversions and promotions
33+
convert{T,f}(::Type{Fixed{T,f}}, x::Integer) = Fixed{T,f}(convert(T,x)<<f,0)
34+
convert{T,f}(::Type{Fixed{T,f}}, x::AbstractFloat) = Fixed{T,f}(trunc(T,x)<<f + round(T, rem(x,1)*(1<<f)),0)
35+
convert{T,f}(::Type{Fixed{T,f}}, x::Rational) = Fixed{T,f}(x.num)/Fixed{T,f}(x.den)
36+
37+
convert{T,f}(::Type{BigFloat}, x::Fixed{T,f}) =
38+
convert(BigFloat,x.i>>f) + convert(BigFloat,x.i&(1<<f - 1))/convert(BigFloat,1<<f)
39+
convert{TF<:AbstractFloat,T,f}(::Type{TF}, x::Fixed{T,f}) =
40+
convert(TF,x.i>>f) + convert(TF,x.i&(1<<f - 1))/convert(TF,1<<f)
41+
42+
convert{T,f}(::Type{Bool}, x::Fixed{T,f}) = x.i!=0
43+
function convert{TI<:Integer, T,f}(::Type{TI}, x::Fixed{T,f})
44+
isinteger(x) || throw(InexactError())
45+
convert(TI, x.i>>f)
46+
end
47+
48+
convert{TR<:Rational,T,f}(::Type{TR}, x::Fixed{T,f}) =
49+
convert(TR, x.i>>f + (x.i&(1<<f-1))//(1<<f))
50+
51+
promote_rule{T,f,TI<:Integer}(ft::Type{Fixed{T,f}}, ::Type{TI}) = Fixed{T,f}
52+
promote_rule{T,f,TF<:AbstractFloat}(::Type{Fixed{T,f}}, ::Type{TF}) = TF
53+
promote_rule{T,f,TR}(::Type{Fixed{T,f}}, ::Type{Rational{TR}}) = Rational{TR}
54+
55+
# TODO: Document and check that it still does the right thing.
56+
decompose{T,f}(x::Fixed{T,f}) = x.i, -f, 1
57+
58+
# printing
59+
function show(io::IO, x::Fixed)
60+
print(io, typeof(x))
61+
print(io, "(")
62+
showcompact(io, x)
63+
print(io, ")")
64+
end
65+
const _log2_10 = 3.321928094887362
66+
showcompact{T,f}(io::IO, x::Fixed{T,f}) = show(io, round(convert(Float64,x), ceil(Int,f/_log2_10)))

src/fixed32.jl

Lines changed: 0 additions & 73 deletions
This file was deleted.

0 commit comments

Comments
 (0)