Skip to content

Commit 6242f82

Browse files
committed
Add big() and rationalize() for FixedPoint
1 parent 7c90fb6 commit 6242f82

File tree

3 files changed

+43
-14
lines changed

3 files changed

+43
-14
lines changed

src/FixedPointNumbers.jl

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import Base: ==, <, <=, -, +, *, /, ~, isapprox,
44
convert, promote_rule, show, isinteger, abs, decompose,
55
isnan, isinf, isfinite,
66
zero, oneunit, one, typemin, typemax, floatmin, floatmax, eps, reinterpret,
7-
float, trunc, round, floor, ceil, bswap,
7+
big, rationalize, float, trunc, round, floor, ceil, bswap,
88
div, fld, rem, mod, mod1, fld1, min, max, minmax,
99
rand, length
1010

@@ -71,6 +71,14 @@ function (::Type{Ti})(x::FixedPoint) where {Ti <: Integer}
7171
end
7272
Base.Rational{Ti}(x::FixedPoint) where {Ti <: Integer} = Rational{Ti}(Rational(x))
7373

74+
big(::Type{<:FixedPoint}) = BigFloat
75+
big(x::FixedPoint) = convert(BigFloat, x)
76+
77+
rationalize(x::FixedPoint; tol::Real=eps(x)) = rationalize(Int, x, tol=tol)
78+
function rationalize(::Type{Ti}, x::FixedPoint; tol::Real=eps(x)) where Ti <: Integer
79+
tol <= eps(x) ? Rational{Ti}(x) : rationalize(Ti, float(x), tol)
80+
end
81+
7482
"""
7583
isapprox(x::FixedPoint, y::FixedPoint; rtol=0, atol=max(eps(x), eps(y)))
7684

test/fixed.jl

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -253,14 +253,6 @@ end
253253
@test varm(a, m) === varm(af, m)
254254
end
255255

256-
@testset "convert result type" begin
257-
x = Fixed{Int8,7}(0.75)
258-
for T in (Float16, Float32, Float64, BigFloat)
259-
y = convert(T, x)
260-
@test isa(y, T)
261-
end
262-
end
263-
264256
@testset "bool conversions" begin
265257
@test convert(Bool, 0.0Q1f6) === false
266258
@test convert(Bool, 1.0Q1f6) === true
@@ -269,7 +261,7 @@ end
269261
@test_broken convert(Bool, Fixed{Int8,8}(0.2)) # TODO: remove this
270262
end
271263

272-
@testset "Integer conversions" begin
264+
@testset "integer conversions" begin
273265
@test convert(Int, Q1f6(1)) === 1
274266
@test convert(Integer, Q1f6(1)) === Int8(1)
275267
@test convert(UInt, 1Q1f6) === UInt(1)
@@ -280,7 +272,19 @@ end
280272
@testset "rational conversions" begin
281273
@test convert(Rational, -0.75Q1f6) === Rational{Int8}(-3//4)
282274
@test convert(Rational, -0.75Q0f7) === Rational{Int16}(-3//4)
283-
@test convert(Rational{Int}, -0.75Q0f7) === Rational(-3//4)
275+
@test convert(Rational{Int}, -0.75Q0f7) === Rational{Int}(-3//4)
276+
277+
@test rationalize(-0.75Q3f4) === Rational{Int}(-3//4)
278+
@test rationalize(Int16, 0.81Q3f4) === Rational{Int16}(13//16)
279+
@test rationalize(-0.81Q3f4, tol=0.02) === Rational{Int}(-13//16)
280+
@test rationalize(Int8, -0.81Q3f4, tol=0.07) === Rational{Int8}(-3//4)
281+
end
282+
283+
@testset "BigFloat conversions" begin
284+
@test convert(BigFloat, -0.75Q0f7)::BigFloat == big"-0.75"
285+
286+
@test big(Q7f0) === BigFloat # !== BigInt
287+
@test big(0.75Q3f4)::BigFloat == big"0.75"
284288
end
285289

286290
@testset "Floating-point conversions" begin
@@ -290,7 +294,7 @@ end
290294
end
291295

292296
@testset "conversions to float" begin
293-
for T in (Float16, Float32, Float64, BigFloat)
297+
for T in (Float16, Float32, Float64)
294298
@test isa(convert(T, Q0f7(0.3)), T)
295299
end
296300

test/normed.jl

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,6 @@ end
110110
@test convert(Integer, one(T)) == 1
111111
@test convert(Rational, one(T)) == 1
112112
end
113-
@test convert(Rational, convert(N0f8, 0.5)) == 0x80//0xff
114113
@test convert(N0f16, one(N0f8)) === one(N0f16)
115114
@test convert(N0f16, N0f8(0.5)).i === 0x8080
116115
@test convert(Normed{UInt16,7}, Normed{UInt8,7}(0.504)) === Normed{UInt16,7}(0.504)
@@ -124,6 +123,24 @@ end
124123
@test_throws InexactError convert(Int8, 256N8f8)
125124
end
126125

126+
@testset "rational conversions" begin
127+
@test convert(Rational, 0.5N0f8) === Rational{UInt8}(0x80//0xff)
128+
@test convert(Rational, 0.5N4f12) === Rational{UInt16}(0x800//0xfff)
129+
@test convert(Rational{Int}, 0.5N0f8) === Rational{Int}(0x80//0xff)
130+
131+
@test rationalize(0.8N0f8) === Rational{Int}(4//5)
132+
@test rationalize(Int16, 0.804N0f8) === Rational{Int16}(41//51)
133+
@test rationalize(0.804N0f8, tol=0.002) === Rational{Int}(41//51)
134+
@test rationalize(Int8, 0.804N0f8, tol=0.005) === Rational{Int8}(4//5)
135+
end
136+
137+
@testset "BigFloat conversions" begin
138+
@test convert(BigFloat, 0.5N0f8)::BigFloat == 128 / big"255"
139+
140+
@test big(N7f1) === BigFloat # !== BigInt
141+
@test big(0.5N4f4)::BigFloat == 8 / big"15"
142+
end
143+
127144
@testset "conversion from float" begin
128145
# issue 102
129146
for T in (UInt8, UInt16, UInt32, UInt64, UInt128)
@@ -158,7 +175,7 @@ end
158175

159176
@testset "conversions to float" begin
160177
x = N0f8(0.3)
161-
for T in (Float16, Float32, Float64, BigFloat)
178+
for T in (Float16, Float32, Float64)
162179
y = convert(T, x)
163180
@test isa(y, T)
164181
end

0 commit comments

Comments
 (0)