@@ -53,19 +53,19 @@ for fn in [:trunc, :floor, :ceil]
53
53
`$($ fn) (x * y)`.
54
54
""" function $ fnname end
55
55
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)
57
57
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)... )
59
59
end
60
60
61
61
if fn === :trunc
62
62
# 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 }
64
64
copysign (floormul (I, abs (x), abs (y)), x* y)
65
65
end
66
66
else
67
67
# 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 }
69
69
a = x * y
70
70
b = fma (x, y, - a)
71
71
if signbit (b)
83
83
A fixed-point decimal type backed by integral type `T`, with `f` digits after
84
84
the decimal point stored.
85
85
"""
86
- immutable FixedDecimal{T <: Integer , f} <: Real
86
+ struct FixedDecimal{T <: Integer , f} <: Real
87
87
i:: T
88
88
89
89
# 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}
91
91
n = max_exp10 (T)
92
92
if f >= 0 && (n < 0 || f <= n)
93
93
new {T, f} (i % T)
@@ -102,23 +102,23 @@ end
102
102
103
103
const FD = FixedDecimal
104
104
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
108
108
109
109
# 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))
112
112
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)
115
115
116
116
# 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}
118
118
i = widemul (x. i, y. i)
119
119
reinterpret (FD{typeof (i), f + g}, i)
120
120
end
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}
122
122
i = widemul (x. i, y)
123
123
reinterpret (FD{typeof (i), f}, i)
124
124
end
@@ -132,7 +132,7 @@ Round `quotient + remainder / divisor` to the nearest even integer, given that
132
132
satisfied by the return value of `fldmod` in all cases, and the return value of
133
133
`divrem` in cases where `divisor` is known to be positive.)
134
134
"""
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 }
136
136
halfdivisor = divisor >> 1
137
137
if iseven (divisor) && remainder == halfdivisor
138
138
ifelse (iseven (quotient), quotient, quotient + one (quotient))
@@ -147,48 +147,48 @@ _round_to_even(q, r, d) = _round_to_even(promote(q, r, d)...)
147
147
# multiplication rounds to nearest even representation
148
148
# TODO : can we use floating point to speed this up? after we build a
149
149
# 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}
151
151
powt = coefficient (FD{T, f})
152
152
quotient, remainder = fldmod (widemul (x. i, y. i), powt)
153
153
reinterpret (FD{T, f}, _round_to_even (quotient, remainder, powt))
154
154
end
155
155
156
156
# these functions are needed to avoid InexactError when converting from the
157
157
# 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))
160
160
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}
162
162
powt = coefficient (FD{T, f})
163
163
quotient, remainder = fldmod (widemul (x. i, powt), y. i)
164
164
reinterpret (FD{T, f}, T (_round_to_even (quotient, remainder, y. i)))
165
165
end
166
166
167
167
# These functions allow us to perform division with integers outside of the range of the
168
168
# FixedDecimal.
169
- function / {T, f} (x:: Integer , y:: FD{T, f} )
169
+ function / (x:: Integer , y:: FD{T, f} ) where {T, f}
170
170
powt = coefficient (FD{T, f})
171
171
powtsq = widemul (powt, powt)
172
172
quotient, remainder = fldmod (widemul (x, powtsq), y. i)
173
173
reinterpret (FD{T, f}, T (_round_to_even (quotient, remainder, y. i)))
174
174
end
175
175
176
- function / {T, f} (x:: FD{T, f} , y:: Integer )
176
+ function / (x:: FD{T, f} , y:: Integer ) where {T, f}
177
177
quotient, remainder = fldmod (x. i, y)
178
178
reinterpret (FD{T, f}, T (_round_to_even (quotient, remainder, y)))
179
179
end
180
180
181
181
# 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})))
184
184
185
185
# 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}
187
187
powt = coefficient (FD{T, f})
188
188
quotient, remainder = fldmod (x. i, powt)
189
189
FD {T, f} (_round_to_even (quotient, remainder, powt))
190
190
end
191
- function ceil {T, f} (x:: FD{T, f} )
191
+ function ceil (x:: FD{T, f} ) where {T, f}
192
192
powt = coefficient (FD{T, f})
193
193
quotient, remainder = fldmod (x. i, powt)
194
194
if remainder > 0
@@ -216,7 +216,7 @@ Compute `f(T, x, i)::T` but avoiding possible loss of precision from an
216
216
intermediate conversion of `i` to a floating point type by instead using a
217
217
`BigFloat` with sufficient precision if necessary.
218
218
"""
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
220
220
prec = required_precision (i)
221
221
if prec > 53
222
222
setprecision (BigFloat, prec) do
@@ -227,45 +227,45 @@ function _apply_exact_float{T}(f, ::Type{T}, x::FMAFloat, i::Integer)
227
227
end
228
228
end
229
229
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)
231
231
232
232
for 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)
234
234
235
235
# 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}
237
237
powt = coefficient (FD{T, f})
238
238
# Use machine Float64 if possible, but fall back to BigFloat if we need
239
239
# more precision. 4f bits suffices.
240
240
val = _apply_exact_float ($ (Symbol (fn, " mul" )), T, x, powt)
241
241
reinterpret (FD{T, f}, val)
242
242
end
243
243
end
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
246
246
end
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}
248
248
reinterpret (FD{T, f}, round (T, x * coefficient (FD{T, f})))
249
249
end
250
250
251
251
# 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}
253
253
reinterpret (FD{T, f}, round (T, x * coefficient (FD{T, f})))
254
254
end
255
255
256
256
# 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}
258
258
reinterpret (FD{T, f}, T (widemul (x, coefficient (FD{T, f}))))
259
259
end
260
260
261
- convert {T <: FD} (:: Type{T} , x:: AbstractFloat ) = round (T, x)
261
+ convert (:: Type{T} , x:: AbstractFloat ) where {T <: FD } = round (T, x)
262
262
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}
264
264
powt = coefficient (FD{T, f})
265
- reinterpret (FD{T, f}, T (x * powt))
265
+ reinterpret (FD{T, f}, T (x * powt)):: FD{T, f}
266
266
end
267
267
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}
269
269
if f ≥ g
270
270
# Compute `10^(f - g)` without overflow
271
271
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})
283
283
end
284
284
285
285
for 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))
287
287
end
288
288
for 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)
290
290
end
291
291
292
292
convert (:: 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
295
295
end
296
296
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
299
299
end
300
300
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}
302
302
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
304
304
end
305
305
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
307
309
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}
311
313
312
314
# TODO : decide if these are the right semantics;
313
315
# 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}
315
317
FD{promote_type (T, U), max (f, g)}
318
+ end
316
319
317
320
# 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
321
324
322
325
# 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 )
327
330
eps (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)
330
333
331
334
# printing
332
- function print {T} (io:: IO , x:: FD{T, 0} )
335
+ function print (io:: IO , x:: FD{T, 0} ) where T
333
336
print (io, x. i)
334
337
end
335
- function print {T, f} (io:: IO , x:: FD{T, f} )
338
+ function print (io:: IO , x:: FD{T, f} ) where {T, f}
336
339
iscompact = get (io, :compact , false )
337
340
338
341
# note: a is negative if x.i == typemin(x.i)
@@ -354,7 +357,7 @@ function print{T, f}(io::IO, x::FD{T, f})
354
357
print (io, integer, ' .' , fractionchars)
355
358
end
356
359
357
- function show {T, f} (io:: IO , x:: FD{T, f} )
360
+ function show (io:: IO , x:: FD{T, f} ) where {T, f}
358
361
iscompact = get (io, :compact , false )
359
362
if ! iscompact
360
363
print (io, " FixedDecimal{$T ,$f }(" )
@@ -374,7 +377,7 @@ Raises an `InexactError` if any rounding is necessary.
374
377
"""
375
378
const RoundThrows = RoundingMode {:Throw} ()
376
379
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}
378
381
if ! (mode in [RoundThrows, RoundNearest, RoundToZero])
379
382
throw (ArgumentError (" Unhandled rounding mode $mode " ))
380
383
end
@@ -421,7 +424,7 @@ function parse{T, f}(::Type{FD{T, f}}, str::AbstractString, mode::RoundingMode=R
421
424
reinterpret (FD{T, f}, val)
422
425
end
423
426
424
- function parse_round {T} (:: Type{T} , fractional:: AbstractString , :: RoundingMode{:Nearest} )
427
+ function parse_round (:: Type{T} , fractional:: AbstractString , :: RoundingMode{:Nearest} ) where T
425
428
# Note: parsing each digit individually ensures we don't run into an OverflowError
426
429
digits = Int8[parse (Int8, d) for d in fractional]
427
430
for i in length (digits): - 1 : 2
443
446
The highest value of `x` which does not result in an overflow when evaluating `T(10)^x`. For
444
447
types of `T` that do not overflow -1 will be returned.
445
448
"""
446
- function max_exp10 {T <: Integer} (:: Type{T} )
449
+ function max_exp10 (:: Type{T} ) where {T <: Integer }
447
450
applicable (typemax, T) || return - 1
448
451
W = widen (T)
449
452
type_max = W (typemax (T))
466
469
Compute `10^f` as an Integer without overflow. Note that overflow will not occur for any
467
470
constructable `FD{T, f}`.
468
471
"""
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})
471
474
value (fd:: FD ) = fd. i
472
475
473
476
end
0 commit comments