Skip to content

Commit 7df3348

Browse files
committed
Add big() and rationalize() for FixedPoint
1 parent bfb4f47 commit 7df3348

File tree

3 files changed

+44
-15
lines changed

3 files changed

+44
-15
lines changed

src/FixedPointNumbers.jl

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

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

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

test/fixed.jl

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -242,14 +242,6 @@ end
242242
@test prod(a, dims=1) == [acmp]
243243
end
244244

245-
@testset "convert result type" begin
246-
x = Fixed{Int8,7}(0.75)
247-
for T in (Float16, Float32, Float64, BigFloat)
248-
y = convert(T, x)
249-
@test isa(y, T)
250-
end
251-
end
252-
253245
@testset "bool conversions" begin
254246
@test convert(Bool, 0.0Q1f6) === false
255247
@test convert(Bool, 1.0Q1f6) === true
@@ -258,7 +250,7 @@ end
258250
@test_broken convert(Bool, Fixed{Int8,8}(0.2)) # TODO: remove this
259251
end
260252

261-
@testset "Integer conversions" begin
253+
@testset "integer conversions" begin
262254
@test convert(Int, Q1f6(1)) === 1
263255
@test convert(Integer, Q1f6(1)) === Int8(1)
264256
@test convert(UInt, 1Q1f6) === UInt(1)
@@ -269,7 +261,19 @@ end
269261
@testset "rational conversions" begin
270262
@test convert(Rational, -0.75Q1f6) === Rational{Int8}(-3//4)
271263
@test convert(Rational, -0.75Q0f7) === Rational{Int16}(-3//4)
272-
@test convert(Rational{Int}, -0.75Q0f7) === Rational(-3//4)
264+
@test convert(Rational{Int}, -0.75Q0f7) === Rational{Int}(-3//4)
265+
266+
@test rationalize(-0.75Q3f4) === Rational{Int}(-3//4)
267+
@test rationalize(Int16, 0.81Q3f4) === Rational{Int16}(13//16)
268+
@test rationalize(-0.81Q3f4, tol=0.02) === Rational{Int}(-13//16)
269+
@test rationalize(Int8, -0.81Q3f4, tol=0.07) === Rational{Int8}(-3//4)
270+
end
271+
272+
@testset "BigFloat conversions" begin
273+
@test convert(BigFloat, -0.75Q0f7)::BigFloat == big"-0.75"
274+
275+
@test big(Q7f0) === BigFloat # !== BigInt
276+
@test big(0.75Q3f4)::BigFloat == big"0.75"
273277
end
274278

275279
@testset "Floating-point conversions" begin
@@ -279,7 +283,7 @@ end
279283
end
280284

281285
@testset "conversions to float" begin
282-
for T in (Float16, Float32, Float64, BigFloat)
286+
for T in (Float16, Float32, Float64)
283287
@test isa(convert(T, Q0f7(0.3)), T)
284288
end
285289

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)