-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
/
Copy pathrounding.jl
62 lines (55 loc) · 1.47 KB
/
rounding.jl
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
module Rounding
include("fenv_constants.jl")
export
RoundingMode, RoundNearest, RoundToZero, RoundUp, RoundDown, RoundFromZero,
get_rounding, set_rounding, with_rounding
## rounding modes ##
immutable RoundingMode
code::Int
RoundingMode(c::Integer) = new(c)
end
const RoundNearest = RoundingMode(0)
const RoundToZero = RoundingMode(1)
const RoundUp = RoundingMode(2)
const RoundDown = RoundingMode(3)
const RoundFromZero = RoundingMode(4)
function to_fenv(r::RoundingMode)
if r === RoundNearest
JL_FE_TONEAREST
elseif r === RoundToZero
JL_FE_TOWARDZERO
elseif r === RoundUp
JL_FE_UPWARD
elseif r === RoundDown
JL_FE_DOWNWARD
elseif r === RoundFromZero
error("unsupported rounding mode")
else
error("invalid rounding mode")
end
end
function from_fenv(r::Integer)
if r == JL_FE_TONEAREST
return RoundNearest
elseif r == JL_FE_DOWNWARD
return RoundDown
elseif r == JL_FE_UPWARD
return RoundUp
elseif r == JL_FE_TOWARDZERO
return RoundToZero
else
error("invalid rounding mode code")
end
end
set_rounding(r::RoundingMode) = ccall(:fesetround, Cint, (Cint,), to_fenv(r))
get_rounding() = from_fenv(ccall(:fegetround, Cint, ()))
function with_rounding(f::Function, rounding::RoundingMode)
old_rounding = get_rounding()
set_rounding(rounding)
try
return f()
finally
set_rounding(old_rounding)
end
end
end #module