Skip to content

Commit f5a8aa3

Browse files
committed
Fix convert to Float at the input limits
1 parent 83e0b42 commit f5a8aa3

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

src/FixedPointDecimals.jl

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,13 @@ for divfn in [:div, :fld, :fld1]
240240
end
241241

242242
convert(::Type{AbstractFloat}, x::FD) = convert(floattype(typeof(x)), x)
243-
convert{TF <: AbstractFloat, T, f}(::Type{TF}, x::FD{T, f})::TF =
244-
x.i / TF(10)^f
243+
function convert{TF <: AbstractFloat, T, f}(::Type{TF}, x::FD{T, f})::TF
244+
x.i / coefficient(FD{T, f})
245+
end
246+
247+
function convert{TF <: BigFloat, T, f}(::Type{TF}, x::FD{T, f})::TF
248+
BigInt(x.i) / BigInt(coefficient(FD{T, f}))
249+
end
245250

246251
function convert{TI <: Integer, T, f}(::Type{TI}, x::FD{T, f})::TI
247252
isinteger(x) || throw(InexactError())

test/runtests.jl

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,20 @@ end
100100
end
101101
end
102102

103+
@testset "to float" begin
104+
# Convert the rational 5//7 into a FixedDecimal with as much precision as we can
105+
# without using BigInt.
106+
T = Int128
107+
f = FixedPointDecimals.max_exp10(T)
108+
powt = FixedPointDecimals.coefficient(FD{T,f})
109+
val = T(trunc(BigInt, widemul(5//7, powt)))
110+
111+
fd = reinterpret(FD{T,f}, val)
112+
@test convert(Float64, fd) != convert(BigFloat, fd)
113+
@test convert(Float64, fd) == T(val) / T(powt)
114+
@test convert(BigFloat, fd) == BigInt(val) / BigInt(powt)
115+
end
116+
103117
@testset "invalid" begin
104118
@test_throws InexactError convert(FD2, FD4(0.0001))
105119
@test_throws InexactError convert(FD4, typemax(FD2))
@@ -129,6 +143,17 @@ end
129143

130144
@test_throws InexactError convert(FD{T,f}, T(1))
131145

146+
# Converting to a floating-point
147+
fd = reinterpret(FD{T,f}, typemax(T))
148+
@test convert(Float32, fd) == Float32(typemax(T) / powt)
149+
@test convert(Float64, fd) == Float64(typemax(T) / powt)
150+
@test convert(BigFloat, fd) == BigInt(typemax(T)) / powt
151+
152+
fd = reinterpret(FD{T,f}, typemin(T))
153+
@test convert(Float32, fd) == Float32(typemin(T) / powt)
154+
@test convert(Float64, fd) == Float64(typemin(T) / powt)
155+
@test convert(BigFloat, fd) == BigInt(typemin(T)) / powt
156+
132157
# Adjust number of decimal places allowed so we can have `-10 < x < 10` where x is
133158
# a FD{T,f}. Only needed to test `convert(::FD, ::Integer)`
134159
f = FixedPointDecimals.max_exp10(T)

0 commit comments

Comments
 (0)