Skip to content

Commit 69e3eec

Browse files
simonbyrnestevengj
authored andcommitted
use MPFR-style rounding enum (#87)
* use MPFR-style rounding enum * fix clarify setrounding function * fix typo from copying * bump version requirement
1 parent b2c18ea commit 69e3eec

File tree

5 files changed

+51
-10
lines changed

5 files changed

+51
-10
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ os:
55
- osx
66

77
julia:
8-
- 0.6
98
- 0.7
9+
- 1.0
1010
- nightly
1111

1212
notifications:

REQUIRE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
julia 0.6
1+
julia 0.7
22
Compat 0.61.0
33
BinaryProvider
44
SpecialFunctions

appveyor.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
environment:
22
matrix:
3-
- julia_version: 0.6
43
- julia_version: 0.7
4+
- julia_version: 1.0
55
- julia_version: latest
66

77
platform:

src/DecFP.jl

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,41 @@ end
7070

7171
#############################################################################
7272

73-
const rounding = Ref{Ptr{Cuint}}()
73+
@enum DecFPRoundingMode begin
74+
DecFPRoundNearest
75+
DecFPRoundDown
76+
DecFPRoundUp
77+
DecFPRoundToZero
78+
DecFPRoundFromZero
79+
end
7480

75-
# rounding modes, from bid_functions.h
76-
const rounding_c2j = [RoundNearest, RoundDown, RoundUp, RoundToZero, RoundFromZero]
77-
const rounding_j2c = Dict{RoundingMode, UInt32}([(rounding_c2j[i], Cuint(i-1)) for i in 1:length(rounding_c2j)])
81+
Base.convert(::Type{DecFPRoundingMode}, ::RoundingMode{:Nearest}) = DecFPRoundNearest
82+
Base.convert(::Type{DecFPRoundingMode}, ::RoundingMode{:Down}) = DecFPRoundDown
83+
Base.convert(::Type{DecFPRoundingMode}, ::RoundingMode{:Up}) = DecFPRoundUp
84+
Base.convert(::Type{DecFPRoundingMode}, ::RoundingMode{:ToZero}) = DecFPRoundToZero
85+
Base.convert(::Type{DecFPRoundingMode}, ::RoundingMode{:FromZero}) = DecFPRoundFromZero
86+
87+
function Base.convert(::Type{RoundingMode}, r::DecFPRoundingMode)
88+
if r == DecFPRoundNearest
89+
return RoundNearest
90+
elseif r == DecFPRRoundDown
91+
return RoundDown
92+
elseif r == DecFPRRoundUp
93+
return RoundUp
94+
elseif r == DecFPRRoundToZero
95+
return RoundToZero
96+
elseif r == DecFPRRoundFromZero
97+
return RoundFromZero
98+
else
99+
throw(ArgumentError("invalid DecFP rounding mode code: $c"))
100+
end
101+
end
102+
103+
const ROUNDING_PTR = Ref{Ptr{DecFPRoundingMode}}()
78104

79105
# global pointers and dicts must be initialized at runtime (via __init__)
80106
function __init__()
81-
global rounding[] = cglobal((:__bid_IDEC_glbround, libbid), Cuint) # rounding mode
107+
global ROUNDING_PTR[] = cglobal((:__bid_IDEC_glbround, libbid), DecFPRoundingMode) # rounding mode
82108
global flags[] = cglobal((:__bid_IDEC_glbflags, libbid), Cuint) # exception status
83109
unsafe_store!(flags[], 0)
84110
end
@@ -94,8 +120,16 @@ const INEXACT = 0x20
94120
bidsym(w,s...) = string("__bid", w, "_", s...)
95121

96122
abstract type DecimalFloatingPoint <: AbstractFloat end
97-
Base.rounding(::Type{T}) where {T<:DecimalFloatingPoint} = rounding_c2j[unsafe_load(rounding[])+1]
98-
Base.setrounding(::Type{T}, r::RoundingMode) where {T<:DecimalFloatingPoint} = unsafe_store!(rounding[], rounding_j2c[r])
123+
124+
Base.Rounding.rounding_raw(::Type{T}) where {T<:DecimalFloatingPoint} =
125+
unsafe_load(ROUNDING_PTR[])
126+
Base.Rounding.setrounding_raw(::Type{T}, r::DecFPRoundingMode) where {T<:DecimalFloatingPoint} =
127+
unsafe_store!(ROUNDING_PTR[],r)
128+
129+
Base.Rounding.rounding(::Type{T}) where {T<:DecimalFloatingPoint} =
130+
convert(RoundingMode, Base.Rounding.rounding_raw(T))
131+
Base.Rounding.setrounding(::Type{T}, r::RoundingMode) where {T<:DecimalFloatingPoint} =
132+
Base.Rounding.setrounding_raw(T, convert(DecFPRoundingMode, r))
99133

100134
for w in (32,64,128)
101135
BID = Symbol(string("Dec",w))

test/runtests.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,3 +219,10 @@ end
219219
@test reinterpret(UInt128, Dec128(1.5)) == 0x303e000000000000000000000000000f
220220
# issue #38
221221
@test collect(v for i in 1:1, v in zeros(Dec128, 1)) == zeros(Dec128, 1, 1)
222+
223+
@test setrounding(Dec64, RoundDown) do
224+
Float64(d64"1e100") < 1e100
225+
end
226+
227+
@test Float64(d64"1e100") == 1e100
228+

0 commit comments

Comments
 (0)