-
Notifications
You must be signed in to change notification settings - Fork 36
Expand file tree
/
Copy patharithmetic.jl
More file actions
126 lines (98 loc) · 3.34 KB
/
arithmetic.jl
File metadata and controls
126 lines (98 loc) · 3.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
module FixedPointArithmetic
using ..FixedPointNumbers
import Base: -, +, *, /, abs, div, fld, cld, rem, mod
module Wrapping
export wrapping_neg, wrapping_abs, wrapping_add, wrapping_sub, wrapping_mul,
wrapping_div, wrapping_fld, wrapping_cld, wrapping_rem, wrapping_mod,
wrapping_fdiv
for name in names(Wrapping)
startswith(string(name), "wrapping_") || continue
@eval function $name end
end
end # module Wrapping
module Saturating
export saturating_neg, saturating_abs, saturating_add, saturating_sub, saturating_mul,
saturating_div, saturating_fld, saturating_cld, saturating_rem, saturating_mod,
saturating_fdiv
for name in names(Saturating)
startswith(string(name), "saturating_") || continue
@eval function $name end
end
end # module Saturating
module Checked
import Base.Checked: checked_neg, checked_abs, checked_add, checked_sub, checked_mul,
checked_div, checked_fld, checked_cld, checked_rem, checked_mod
export checked_neg, checked_abs, checked_add, checked_sub, checked_mul,
checked_div, checked_fld, checked_cld, checked_rem, checked_mod,
checked_fdiv
function checked_fdiv end
end # module Checked
module Unchecked
using ..FixedPointNumbers
using ..Wrapping
export unchecked_neg, unchecked_abs, unchecked_add, unchecked_sub, unchecked_mul,
unchecked_div, unchecked_fld, unchecked_cld, unchecked_rem, unchecked_mod,
unchecked_fdiv
for name in (:neg, :abs)
fu = Symbol(:unchecked_, name)
fw = Symbol(:wrapping_, name)
@eval begin
$fu(x::X) where {X <: FixedPoint} = $fw(x)
end
end
for name in (:add, :sub, :mul, :div, :fld, :cld, :rem, :mod, :fdiv)
fu = Symbol(:unchecked_, name)
fw = Symbol(:wrapping_, name)
@eval begin
$fu(x::X, y::X) where {X <: FixedPoint} = $fw(x, y)
end
name in (:div, :rem) || continue
@eval begin
$fu(x::X, y::X, r::RoundingMode{M}) where {X <: FixedPoint, M} = $fw(x, y, r)
end
end
end # module Unchecked
using .Wrapping, .Saturating, .Checked, .Unchecked
# re-export
for Mod in (Wrapping, Saturating, Checked, Unchecked)
for name in names(Mod)
@eval export $name
end
end
# default arithmetic
const DEFAULT_ARITHMETIC = :wrapping
for (op, name) in ((:-, :neg), (:abs, :abs))
f = Symbol(DEFAULT_ARITHMETIC, :_, name)
@eval begin
$op(x::X) where {X <: FixedPoint} = $f(x)
end
end
for (op, name) in ((:+, :add), (:-, :sub), (:*, :mul))
f = Symbol(DEFAULT_ARITHMETIC, :_, name)
@eval begin
$op(x::X, y::X) where {X <: FixedPoint} = $f(x, y)
end
end
const DEFAULT_DIV_ARITHMETIC = :checked
for name in (:fdiv, :div, :fld, :cld, :rem, :mod)
f = Symbol(DEFAULT_DIV_ARITHMETIC, :_, name)
if name === :fdiv
@eval begin
/(x::X, y::X) where {X <: FixedPoint} = $f(x, y)
end
continue
end
@eval begin
$name(x::X, y::X) where {X <: FixedPoint} = $f(x, y)
end
name in (:div, :rem) || continue
end
for m in (:(:Nearest), :(:ToZero), :(:Up), :(:Down))
_div = Symbol(DEFAULT_DIV_ARITHMETIC, :_div)
_rem = Symbol(DEFAULT_DIV_ARITHMETIC, :_rem)
@eval begin
div(x::X, y::X, r::RoundingMode{$m}) where {X <: FixedPoint} = $_div(x, y, r)
rem(x::X, y::X, r::RoundingMode{$m}) where {X <: FixedPoint} = $_rem(x, y, r)
end
end
end # module FixedPointArithmetic