You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
rationalize is a useful way to convert from floats to rational numbers. It would be useful to use it directly with SimpleRatio, rather than needing to convert from Rational{Int}.
Here's the source code in Julia base:
Perhaps the easiest thing to do would be to copy this code, and replace the np // nq at the end with SimpleRatio(np, nq)? What do you think?
""" rationalize([T<:Integer=Int,] x; tol::Real=eps(x))Approximate floating point number `x` as a [`Rational`](@ref) number with componentsof the given integer type. The result will differ from `x` by no more than `tol`.# Examples\```jldoctestjulia> rationalize(5.6)28//5julia> a = rationalize(BigInt, 10.3)103//10julia> typeof(numerator(a))BigInt\```"""functionrationalize(::Type{T}, x::AbstractFloat, tol::Real) where T<:Integerif tol <0throw(ArgumentError("negative tolerance $tol"))
end
T<:Unsigned&& x <0&&__throw_negate_unsigned()
isnan(x) &&returnT(x)//one(T)
isinf(x) &&returnunsafe_rational(x <0?-one(T) :one(T), zero(T))
p, q = (x <0?-one(T) :one(T)), zero(T)
pp, qq =zero(T), one(T)
x =abs(x)
a =trunc(x)
r = x-a
y =one(x)
tolx =oftype(x, tol)
nt, t, tt = tolx, zero(tolx), tolx
ia = np = nq =zero(T)
# compute the successive convergents of the continued fraction# np // nq = (p*a + pp) // (q*a + qq)while r > nt
try
ia =convert(T,a)
np =checked_add(checked_mul(ia,p),pp)
nq =checked_add(checked_mul(ia,q),qq)
p, pp = np, p
q, qq = nq, q
catch e
isa(e,InexactError) ||isa(e,OverflowError) ||rethrow()
return p // q
end# naive approach of using# x = 1/r; a = trunc(x); r = x - a# is inexact, so we store x as x/y
x, y = y, r
a, r =divrem(x,y)
# maintain# x0 = (p + (-1)^i * r) / q
t, tt = nt, t
nt = a*t+tt
end# find optimal semiconvergent# smallest a such that x-a*y < a*t+tt
a =cld(x-tt,y+t)
try
ia =convert(T,a)
np =checked_add(checked_mul(ia,p),pp)
nq =checked_add(checked_mul(ia,q),qq)
return np // nq
catch e
isa(e,InexactError) ||isa(e,OverflowError) ||rethrow()
return p // q
endendrationalize(::Type{T}, x::AbstractFloat; tol::Real=eps(x)) where {T<:Integer} =rationalize(T, x, tol)::Rational{T}rationalize(x::AbstractFloat; kvs...) =rationalize(Int, x; kvs...)
rationalize(::Type{T}, x::Complex; kvs...) where {T<:Integer} =Complex(rationalize(T, x.re, kvs...)::Rational{T}, rationalize(T, x.im, kvs...)::Rational{T})
rationalize(x::Complex; kvs...) =Complex(rationalize(Int, x.re, kvs...), rationalize(Int, x.im, kvs...))
The text was updated successfully, but these errors were encountered:
I think that's the best option, yeah. Given that you would otherwise need to provide the parameter as input to rationalize, rather than just Rational/SimpleRational.
rationalize
is a useful way to convert from floats to rational numbers. It would be useful to use it directly withSimpleRatio
, rather than needing to convert fromRational{Int}
.Here's the source code in Julia base:
Perhaps the easiest thing to do would be to copy this code, and replace the
np // nq
at the end withSimpleRatio(np, nq)
? What do you think?The text was updated successfully, but these errors were encountered: