@@ -53,19 +53,19 @@ for fn in [:trunc, :floor, :ceil]
5353 `$($ fn) (x * y)`.
5454 """ function $ fnname end
5555
56- $ fnname {I, T <: Number} (:: Type{I} , x:: T , y:: T ) = $ fn (I, x * y)
56+ $ fnname (:: Type{I} , x:: T , y:: T ) where {I, T <: Number } = $ fn (I, x * y)
5757
58- $ fnname {I} (:: Type{I} , x:: Number , y:: Number ) = $ fnname (I, promote (x, y)... )
58+ $ fnname (:: Type{I} , x:: Number , y:: Number ) where I = $ fnname (I, promote (x, y)... )
5959 end
6060
6161 if fn === :trunc
6262 # trunc a little different, implement in terms of floor
63- @eval function $fnname {I, T <: FMAFloat} (:: Type{I} , x:: T , y:: T )
63+ @eval function $fnname (:: Type{I} , x:: T , y:: T ) where {I, T <: FMAFloat }
6464 copysign (floormul (I, abs (x), abs (y)), x* y)
6565 end
6666 else
6767 # floor and ceil can be implemented the same way
68- @eval function $fnname {I, T <: FMAFloat} (:: Type{I} , x:: T , y:: T )
68+ @eval function $fnname (:: Type{I} , x:: T , y:: T ) where {I, T <: FMAFloat }
6969 a = x * y
7070 b = fma (x, y, - a)
7171 if signbit (b)
8383A fixed-point decimal type backed by integral type `T`, with `f` digits after
8484the decimal point stored.
8585"""
86- immutable FixedDecimal{T <: Integer , f} <: Real
86+ struct FixedDecimal{T <: Integer , f} <: Real
8787 i:: T
8888
8989 # inner constructor
90- function Base. reinterpret {T, f} (:: Type{FixedDecimal{T, f}} , i:: Integer )
90+ function Base. reinterpret (:: Type{FixedDecimal{T, f}} , i:: Integer ) where {T, f}
9191 n = max_exp10 (T)
9292 if f >= 0 && (n < 0 || f <= n)
9393 new {T, f} (i % T)
@@ -102,23 +102,23 @@ end
102102
103103const FD = FixedDecimal
104104
105- floattype {T <:Union{Int8, UInt8, Int16, UInt16}, f} ( :: Type{FD{T, f}} ) = Float32
106- floattype {T<:Integer, f} (:: Type{FD{T, f }} ) = Float64
107- floattype {f} (:: Type{FD{BigInt, f }} ) = BigFloat
105+ floattype ( :: Type{<:FD{T}} ) where {T <: Union{Int8, UInt8, Int16, UInt16} } = Float32
106+ floattype (:: Type{<: FD{T}} ) where {T <: Integer } = Float64
107+ floattype (:: Type{<: FD{BigInt}} ) = BigFloat
108108
109109# basic operators
110- - {T, f} (x:: FD{T, f} ) = reinterpret (FD{T, f}, - x. i)
111- abs {T, f} (x:: FD{T, f} ) = reinterpret (FD{T, f}, abs (x. i))
110+ - (x:: FD{T, f} ) where {T, f} = reinterpret (FD{T, f}, - x. i)
111+ abs (x:: FD{T, f} ) where {T, f} = reinterpret (FD{T, f}, abs (x. i))
112112
113- + {T, f} (x:: FD{T, f} , y:: FD{T, f} ) = reinterpret (FD{T, f}, x. i+ y. i)
114- - {T, f} (x:: FD{T, f} , y:: FD{T, f} ) = reinterpret (FD{T, f}, x. i- y. i)
113+ + (x:: FD{T, f} , y:: FD{T, f} ) where {T, f} = reinterpret (FD{T, f}, x. i+ y. i)
114+ - (x:: FD{T, f} , y:: FD{T, f} ) where {T, f} = reinterpret (FD{T, f}, x. i- y. i)
115115
116116# wide multiplication
117- Base. @pure function widemul {T, f, U, g} (x:: FD{T , f} , y:: FD{U , g} )
117+ Base. @pure function widemul (x:: FD{<:Any , f} , y:: FD{<:Any , g} ) where {f, g}
118118 i = widemul (x. i, y. i)
119119 reinterpret (FD{typeof (i), f + g}, i)
120120end
121- Base. @pure function widemul {T, f} (x:: FD{T, f} , y:: Integer )
121+ Base. @pure function widemul (x:: FD{T, f} , y:: Integer ) where {T, f}
122122 i = widemul (x. i, y)
123123 reinterpret (FD{typeof (i), f}, i)
124124end
@@ -132,7 +132,7 @@ Round `quotient + remainder / divisor` to the nearest even integer, given that
132132satisfied by the return value of `fldmod` in all cases, and the return value of
133133`divrem` in cases where `divisor` is known to be positive.)
134134"""
135- function _round_to_even {T <: Integer} (quotient:: T , remainder:: T , divisor:: T )
135+ function _round_to_even (quotient:: T , remainder:: T , divisor:: T ) where {T <: Integer }
136136 halfdivisor = divisor >> 1
137137 if iseven (divisor) && remainder == halfdivisor
138138 ifelse (iseven (quotient), quotient, quotient + one (quotient))
@@ -147,48 +147,48 @@ _round_to_even(q, r, d) = _round_to_even(promote(q, r, d)...)
147147# multiplication rounds to nearest even representation
148148# TODO : can we use floating point to speed this up? after we build a
149149# correctness test suite.
150- function * {T, f} (x:: FD{T, f} , y:: FD{T, f} )
150+ function * (x:: FD{T, f} , y:: FD{T, f} ) where {T, f}
151151 powt = coefficient (FD{T, f})
152152 quotient, remainder = fldmod (widemul (x. i, y. i), powt)
153153 reinterpret (FD{T, f}, _round_to_even (quotient, remainder, powt))
154154end
155155
156156# these functions are needed to avoid InexactError when converting from the
157157# integer type
158- * {T, f} (x:: Integer , y:: FD{T, f} ) = reinterpret (FD{T, f}, T (x * y. i))
159- * {T, f} (x:: FD{T, f} , y:: Integer ) = reinterpret (FD{T, f}, T (x. i * y))
158+ * (x:: Integer , y:: FD{T, f} ) where {T, f} = reinterpret (FD{T, f}, T (x * y. i))
159+ * (x:: FD{T, f} , y:: Integer ) where {T, f} = reinterpret (FD{T, f}, T (x. i * y))
160160
161- function / {T, f} (x:: FD{T, f} , y:: FD{T, f} )
161+ function / (x:: FD{T, f} , y:: FD{T, f} ) where {T, f}
162162 powt = coefficient (FD{T, f})
163163 quotient, remainder = fldmod (widemul (x. i, powt), y. i)
164164 reinterpret (FD{T, f}, T (_round_to_even (quotient, remainder, y. i)))
165165end
166166
167167# These functions allow us to perform division with integers outside of the range of the
168168# FixedDecimal.
169- function / {T, f} (x:: Integer , y:: FD{T, f} )
169+ function / (x:: Integer , y:: FD{T, f} ) where {T, f}
170170 powt = coefficient (FD{T, f})
171171 powtsq = widemul (powt, powt)
172172 quotient, remainder = fldmod (widemul (x, powtsq), y. i)
173173 reinterpret (FD{T, f}, T (_round_to_even (quotient, remainder, y. i)))
174174end
175175
176- function / {T, f} (x:: FD{T, f} , y:: Integer )
176+ function / (x:: FD{T, f} , y:: Integer ) where {T, f}
177177 quotient, remainder = fldmod (x. i, y)
178178 reinterpret (FD{T, f}, T (_round_to_even (quotient, remainder, y)))
179179end
180180
181181# integerification
182- trunc {T, f} (x:: FD{T, f} ) = FD {T, f} (div (x. i, coefficient (FD{T, f})))
183- floor {T, f} (x:: FD{T, f} ) = FD {T, f} (fld (x. i, coefficient (FD{T, f})))
182+ trunc (x:: FD{T, f} ) where {T, f} = FD {T, f} (div (x. i, coefficient (FD{T, f})))
183+ floor (x:: FD{T, f} ) where {T, f} = FD {T, f} (fld (x. i, coefficient (FD{T, f})))
184184
185185# TODO : round with number of digits; should be easy
186- function round {T, f} (x:: FD{T, f} , :: RoundingMode{:Nearest} = RoundNearest)
186+ function round (x:: FD{T, f} , :: RoundingMode{:Nearest} = RoundNearest) where {T, f}
187187 powt = coefficient (FD{T, f})
188188 quotient, remainder = fldmod (x. i, powt)
189189 FD {T, f} (_round_to_even (quotient, remainder, powt))
190190end
191- function ceil {T, f} (x:: FD{T, f} )
191+ function ceil (x:: FD{T, f} ) where {T, f}
192192 powt = coefficient (FD{T, f})
193193 quotient, remainder = fldmod (x. i, powt)
194194 if remainder > 0
@@ -216,7 +216,7 @@ Compute `f(T, x, i)::T` but avoiding possible loss of precision from an
216216intermediate conversion of `i` to a floating point type by instead using a
217217`BigFloat` with sufficient precision if necessary.
218218"""
219- function _apply_exact_float {T} (f, :: Type{T} , x:: FMAFloat , i:: Integer )
219+ function _apply_exact_float (f, :: Type{T} , x:: FMAFloat , i:: Integer ) where T
220220 prec = required_precision (i)
221221 if prec > 53
222222 setprecision (BigFloat, prec) do
@@ -227,45 +227,45 @@ function _apply_exact_float{T}(f, ::Type{T}, x::FMAFloat, i::Integer)
227227 end
228228end
229229
230- _apply_exact_float {T} (f, :: Type{T} , x:: Real , i:: Integer ) = f (T, x, i)
230+ _apply_exact_float (f, :: Type{T} , x:: Real , i:: Integer ) where T = f (T, x, i)
231231
232232for fn in [:trunc , :floor , :ceil ]
233- @eval $ fn {TI <: Integer} (:: Type{TI} , x:: FD ):: TI = $ fn (x)
233+ @eval ( $ fn (:: Type{TI} , x:: FD ):: TI ) where {TI <: Integer } = $ fn (x)
234234
235235 # round/trunc/ceil/flooring to FD; generic
236- @eval function $fn {T, f} (:: Type{FD{T, f}} , x:: Real )
236+ @eval function $fn (:: Type{FD{T, f}} , x:: Real ) where {T, f}
237237 powt = coefficient (FD{T, f})
238238 # Use machine Float64 if possible, but fall back to BigFloat if we need
239239 # more precision. 4f bits suffices.
240240 val = _apply_exact_float ($ (Symbol (fn, " mul" )), T, x, powt)
241241 reinterpret (FD{T, f}, val)
242242 end
243243end
244- function round {TI <: Integer} (:: Type{TI} , x:: FD , :: RoundingMode{:Nearest} = RoundNearest):: TI
245- round (x)
244+ function round (:: Type{TI} , x:: FD , :: RoundingMode{:Nearest} = RoundNearest) where {TI <: Integer }
245+ convert (TI, round (x)) :: TI
246246end
247- function round {T, f} (:: Type{FD{T, f}} , x:: Real , :: RoundingMode{:Nearest} = RoundNearest)
247+ function round (:: Type{FD{T, f}} , x:: Real , :: RoundingMode{:Nearest} = RoundNearest) where {T, f}
248248 reinterpret (FD{T, f}, round (T, x * coefficient (FD{T, f})))
249249end
250250
251251# needed to avoid ambiguity
252- function round {T, f} (:: Type{FD{T, f}} , x:: Rational , :: RoundingMode{:Nearest} = RoundNearest)
252+ function round (:: Type{FD{T, f}} , x:: Rational , :: RoundingMode{:Nearest} = RoundNearest) where {T, f}
253253 reinterpret (FD{T, f}, round (T, x * coefficient (FD{T, f})))
254254end
255255
256256# conversions and promotions
257- function convert {T, f} (:: Type{FD{T, f}} , x:: Integer )
257+ function convert (:: Type{FD{T, f}} , x:: Integer ) where {T, f}
258258 reinterpret (FD{T, f}, T (widemul (x, coefficient (FD{T, f}))))
259259end
260260
261- convert {T <: FD} (:: Type{T} , x:: AbstractFloat ) = round (T, x)
261+ convert (:: Type{T} , x:: AbstractFloat ) where {T <: FD } = round (T, x)
262262
263- function convert {T, f} (:: Type{FD{T, f}} , x:: Rational ):: FD {T, f}
263+ function convert (:: Type{FD{T, f}} , x:: Rational ) where {T, f}
264264 powt = coefficient (FD{T, f})
265- reinterpret (FD{T, f}, T (x * powt))
265+ reinterpret (FD{T, f}, T (x * powt)):: FD{T, f}
266266end
267267
268- function convert {T, f, U, g} (:: Type{FD{T, f}} , x:: FD{U, g} )
268+ function convert (:: Type{FD{T, f}} , x:: FD{U, g} ) where {T, f, U, g}
269269 if f ≥ g
270270 # Compute `10^(f - g)` without overflow
271271 powt = div (coefficient (FD{T, f}), coefficient (FD{U, g}))
@@ -283,56 +283,59 @@ function convert{T, f, U, g}(::Type{FD{T, f}}, x::FD{U, g})
283283end
284284
285285for remfn in [:rem , :mod , :mod1 , :min , :max ]
286- @eval $ remfn {T <: FD} (x:: T , y:: T ) = reinterpret (T, $ remfn (x. i, y. i))
286+ @eval $ remfn (x:: T , y:: T ) where {T <: FD } = reinterpret (T, $ remfn (x. i, y. i))
287287end
288288for divfn in [:div , :fld , :fld1 ]
289- @eval $ divfn {T <: FD} (x:: T , y:: T ) = $ divfn (x. i, y. i)
289+ @eval $ divfn (x:: T , y:: T ) where {T <: FD } = $ divfn (x. i, y. i)
290290end
291291
292292convert (:: Type{AbstractFloat} , x:: FD ) = convert (floattype (typeof (x)), x)
293- function convert {TF <: AbstractFloat, T, f} (:: Type{TF} , x:: FD{T, f} ):: TF
294- x. i / coefficient (FD{T, f})
293+ function convert (:: Type{TF} , x:: FD{T, f} ) where {TF <: AbstractFloat , T, f}
294+ convert (TF, x. i / coefficient (FD{T, f})) :: TF
295295end
296296
297- function convert {TF <: BigFloat, T, f} (:: Type{TF} , x:: FD{T, f} ):: TF
298- BigInt (x. i) / BigInt (coefficient (FD{T, f}))
297+ function convert (:: Type{TF} , x:: FD{T, f} ) where {TF <: BigFloat , T, f}
298+ convert (TF, BigInt (x. i) / BigInt (coefficient (FD{T, f}))) :: TF
299299end
300300
301- function convert {TI <: Integer, T, f} (:: Type{TI} , x:: FD{T, f} ):: TI
301+ function convert (:: Type{TI} , x:: FD{T, f} ) where {TI <: Integer , T, f}
302302 isinteger (x) || throw (InexactError (:convert , TI, x))
303- div (x. i, coefficient (FD{T, f}))
303+ convert (TI, div (x. i, coefficient (FD{T, f}))) :: TI
304304end
305305
306- convert {TR <: Rational, T, f} (:: Type{TR} , x:: FD{T, f} ):: TR = x. i // coefficient (FD{T, f})
306+ function convert (:: Type{TR} , x:: FD{T, f} ) where {TR <: Rational , T, f}
307+ convert (TR, x. i // coefficient (FD{T, f})):: TR
308+ end
307309
308- promote_rule {T, f, TI <: Integer} (:: Type{FD{T, f}} , :: Type{TI} ) = FD{T, f}
309- promote_rule {T, f, TF <: AbstractFloat} (:: Type{FD{T, f}} , :: Type{TF} ) = TF
310- promote_rule {T, f, TR} (:: Type{FD{T, f}} , :: Type{Rational{TR}} ) = Rational{TR}
310+ promote_rule (:: Type{FD{T, f}} , :: Type{<:Integer} ) where {T, f} = FD{T, f}
311+ promote_rule (:: Type{<:FD} , :: Type{TF} ) where {TF <: AbstractFloat } = TF
312+ promote_rule (:: Type{<:FD} , :: Type{Rational{TR}} ) where {TR} = Rational{TR}
311313
312314# TODO : decide if these are the right semantics;
313315# right now we pick the bigger int type and the bigger decimal point
314- Base. @pure promote_rule {T, f, U, g} (:: Type{FD{T, f}} , :: Type{FD{U, g}} ) =
316+ Base. @pure function promote_rule (:: Type{FD{T, f}} , :: Type{FD{U, g}} ) where {T, f, U, g}
315317 FD{promote_type (T, U), max (f, g)}
318+ end
316319
317320# comparison
318- == {T <: FD } (x:: T , y:: T ) = x. i == y. i
319- < {T <: FD } (x:: T , y:: T ) = x. i < y. i
320- <= {T <: FD } (x:: T , y:: T ) = x. i <= y. i
321+ == (x:: T , y:: T ) where {T <: FD } = x. i == y. i
322+ < (x:: T , y:: T ) where {T <: FD } = x. i < y. i
323+ <= (x:: T , y:: T ) where {T <: FD } = x. i <= y. i
321324
322325# predicates and traits
323- isinteger {T, f} (x:: FD{T, f} ) = rem (x. i, coefficient (FD{T, f})) == 0
324- typemin {T, f} (:: Type{FD{T, f}} ) = reinterpret (FD{T, f}, typemin (T))
325- typemax {T, f} (:: Type{FD{T, f}} ) = reinterpret (FD{T, f}, typemax (T))
326- eps {T <: FD} (:: Type{T} ) = reinterpret (T, 1 )
326+ isinteger (x:: FD{T, f} ) where {T, f} = rem (x. i, coefficient (FD{T, f})) == 0
327+ typemin (:: Type{FD{T, f}} ) where {T, f} = reinterpret (FD{T, f}, typemin (T))
328+ typemax (:: Type{FD{T, f}} ) where {T, f} = reinterpret (FD{T, f}, typemax (T))
329+ eps (:: Type{T} ) where {T <: FD } = reinterpret (T, 1 )
327330eps (x:: FD ) = eps (typeof (x))
328- realmin {T <: FD} (:: Type{T} ) = eps (T)
329- realmax {T <: FD} (:: Type{T} ) = typemax (T)
331+ realmin (:: Type{T} ) where {T <: FD } = eps (T)
332+ realmax (:: Type{T} ) where {T <: FD } = typemax (T)
330333
331334# printing
332- function print {T} (io:: IO , x:: FD{T, 0} )
335+ function print (io:: IO , x:: FD{T, 0} ) where T
333336 print (io, x. i)
334337end
335- function print {T, f} (io:: IO , x:: FD{T, f} )
338+ function print (io:: IO , x:: FD{T, f} ) where {T, f}
336339 iscompact = get (io, :compact , false )
337340
338341 # note: a is negative if x.i == typemin(x.i)
@@ -354,7 +357,7 @@ function print{T, f}(io::IO, x::FD{T, f})
354357 print (io, integer, ' .' , fractionchars)
355358end
356359
357- function show {T, f} (io:: IO , x:: FD{T, f} )
360+ function show (io:: IO , x:: FD{T, f} ) where {T, f}
358361 iscompact = get (io, :compact , false )
359362 if ! iscompact
360363 print (io, " FixedDecimal{$T ,$f }(" )
@@ -374,7 +377,7 @@ Raises an `InexactError` if any rounding is necessary.
374377"""
375378const RoundThrows = RoundingMode {:Throw} ()
376379
377- function parse {T, f} (:: Type{FD{T, f}} , str:: AbstractString , mode:: RoundingMode = RoundNearest)
380+ function parse (:: Type{FD{T, f}} , str:: AbstractString , mode:: RoundingMode = RoundNearest) where {T, f}
378381 if ! (mode in [RoundThrows, RoundNearest, RoundToZero])
379382 throw (ArgumentError (" Unhandled rounding mode $mode " ))
380383 end
@@ -421,7 +424,7 @@ function parse{T, f}(::Type{FD{T, f}}, str::AbstractString, mode::RoundingMode=R
421424 reinterpret (FD{T, f}, val)
422425end
423426
424- function parse_round {T} (:: Type{T} , fractional:: AbstractString , :: RoundingMode{:Nearest} )
427+ function parse_round (:: Type{T} , fractional:: AbstractString , :: RoundingMode{:Nearest} ) where T
425428 # Note: parsing each digit individually ensures we don't run into an OverflowError
426429 digits = Int8[parse (Int8, d) for d in fractional]
427430 for i in length (digits): - 1 : 2
443446The highest value of `x` which does not result in an overflow when evaluating `T(10)^x`. For
444447types of `T` that do not overflow -1 will be returned.
445448"""
446- function max_exp10 {T <: Integer} (:: Type{T} )
449+ function max_exp10 (:: Type{T} ) where {T <: Integer }
447450 applicable (typemax, T) || return - 1
448451 W = widen (T)
449452 type_max = W (typemax (T))
466469Compute `10^f` as an Integer without overflow. Note that overflow will not occur for any
467470constructable `FD{T, f}`.
468471"""
469- coefficient {T, f} (:: Type{FD{T, f}} ) = T (10 )^ f
470- coefficient {T, f} (fd:: FD{T, f} ) = coefficient (FD{T, f})
472+ coefficient (:: Type{FD{T, f}} ) where {T, f} = T (10 )^ f
473+ coefficient (fd:: FD{T, f} ) where {T, f} = coefficient (FD{T, f})
471474value (fd:: FD ) = fd. i
472475
473476end
0 commit comments