From 06691ddd1f6c4e27080fb9df2a48e8e69cba721f Mon Sep 17 00:00:00 2001 From: tantheta01 Date: Wed, 15 Dec 2021 14:46:11 +0530 Subject: [PATCH 01/11] Add Method to Rationalize Rational --- base/rational.jl | 14 +++++++++++--- test/rational.jl | 2 ++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/base/rational.jl b/base/rational.jl index 9e887bdaefa91..4d0c121f68018 100644 --- a/base/rational.jl +++ b/base/rational.jl @@ -158,6 +158,7 @@ function rationalize(::Type{T}, x::AbstractFloat, tol::Real) where T<:Integer if tol < 0 throw(ArgumentError("negative tolerance $tol")) end + T<:Unsigned && x < 0 && __throw_negate_unsigned() isnan(x) && return T(x)//one(T) isinf(x) && return unsafe_rational(x < 0 ? -one(T) : one(T), zero(T)) @@ -169,7 +170,6 @@ function rationalize(::Type{T}, x::AbstractFloat, tol::Real) where T<:Integer 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) @@ -216,8 +216,16 @@ function rationalize(::Type{T}, x::AbstractFloat, tol::Real) where T<:Integer end rationalize(::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...)) +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...)) +rationalize(::Type{T}, x::Rational, tol::Real) where {T<:Integer} = rationalize(T, float(x), tol)::Rational{T} +rationalize(::Type{T}, x::Rational; tol::Real = zero(x)) where {T<:Integer} = rationalize(T, float(x), tol)::Rational{T} +rationalize(x::Rational; kvs...) = rationalize(Int, x; kvs...) +rationalize(::Type{T}, x::Integer, tol::Real) where {T<:Integer} = rationalize(T, Rational(x, 1), tol) +rationalize(::Type{T}, x::Integer; tol::Real = 0) where {T<:Integer} = Rational(x, 1) +rationalize(x::Integer; kvs...) = Rational(x, 1) + + """ numerator(x) diff --git a/test/rational.jl b/test/rational.jl index 1618156212af7..41f37f8267765 100644 --- a/test/rational.jl +++ b/test/rational.jl @@ -33,6 +33,8 @@ using Test @test @inferred(rationalize(Int, 3.0, 0.0)) === 3//1 @test @inferred(rationalize(Int, 3.0, 0)) === 3//1 + @test @inferred(rationalize(Int, 33//100, 0.1)) === 1//3 + @test @inferred(rationalize(Int, 3, 0.0)) === 3//1 @test_throws OverflowError rationalize(UInt, -2.0) @test_throws ArgumentError rationalize(Int, big(3.0), -1.) # issue 26823 From 32497af1ace337f1514d2e277a097b8a4eb4b3c9 Mon Sep 17 00:00:00 2001 From: Tanay Sharma <190050122@iitb.ac.in> Date: Fri, 17 Dec 2021 16:22:36 +0530 Subject: [PATCH 02/11] Update base/rational.jl Co-authored-by: Jeff Bezanson --- base/rational.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/rational.jl b/base/rational.jl index 4d0c121f68018..a7a51d9a8b2c3 100644 --- a/base/rational.jl +++ b/base/rational.jl @@ -223,7 +223,7 @@ rationalize(::Type{T}, x::Rational; tol::Real = zero(x)) where {T<:Integer} = ra rationalize(x::Rational; kvs...) = rationalize(Int, x; kvs...) rationalize(::Type{T}, x::Integer, tol::Real) where {T<:Integer} = rationalize(T, Rational(x, 1), tol) rationalize(::Type{T}, x::Integer; tol::Real = 0) where {T<:Integer} = Rational(x, 1) -rationalize(x::Integer; kvs...) = Rational(x, 1) +rationalize(x::Integer; kvs...) = Rational(x) From 25edfefedf910eb956cb91f7009d49ca3a4b1750 Mon Sep 17 00:00:00 2001 From: Tanay Sharma <190050122@iitb.ac.in> Date: Fri, 17 Dec 2021 16:22:55 +0530 Subject: [PATCH 03/11] Update base/rational.jl Co-authored-by: Jeff Bezanson --- base/rational.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/rational.jl b/base/rational.jl index a7a51d9a8b2c3..0f5af29a6d273 100644 --- a/base/rational.jl +++ b/base/rational.jl @@ -220,7 +220,7 @@ rationalize(::Type{T}, x::Complex; kvs...) where {T<:Integer} = Complex(rational rationalize(x::Complex; kvs...) = Complex(rationalize(Int, x.re; kvs...), rationalize(Int, x.im; kvs...)) rationalize(::Type{T}, x::Rational, tol::Real) where {T<:Integer} = rationalize(T, float(x), tol)::Rational{T} rationalize(::Type{T}, x::Rational; tol::Real = zero(x)) where {T<:Integer} = rationalize(T, float(x), tol)::Rational{T} -rationalize(x::Rational; kvs...) = rationalize(Int, x; kvs...) +rationalize(x::Rational{T}; kvs...) where{T} = rationalize(T, x; kvs...) rationalize(::Type{T}, x::Integer, tol::Real) where {T<:Integer} = rationalize(T, Rational(x, 1), tol) rationalize(::Type{T}, x::Integer; tol::Real = 0) where {T<:Integer} = Rational(x, 1) rationalize(x::Integer; kvs...) = Rational(x) From c06b479ac813c685ea1a426aec944c087e11b827 Mon Sep 17 00:00:00 2001 From: Tanay Sharma <190050122@iitb.ac.in> Date: Sun, 19 Dec 2021 13:08:28 +0530 Subject: [PATCH 04/11] Update base/rational.jl Co-authored-by: Jeff Bezanson --- base/rational.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/rational.jl b/base/rational.jl index 0f5af29a6d273..12da98f999149 100644 --- a/base/rational.jl +++ b/base/rational.jl @@ -221,7 +221,7 @@ rationalize(x::Complex; kvs...) = Complex(rationalize(Int, x.re; kvs...), ration rationalize(::Type{T}, x::Rational, tol::Real) where {T<:Integer} = rationalize(T, float(x), tol)::Rational{T} rationalize(::Type{T}, x::Rational; tol::Real = zero(x)) where {T<:Integer} = rationalize(T, float(x), tol)::Rational{T} rationalize(x::Rational{T}; kvs...) where{T} = rationalize(T, x; kvs...) -rationalize(::Type{T}, x::Integer, tol::Real) where {T<:Integer} = rationalize(T, Rational(x, 1), tol) +rationalize(::Type{T}, x::Integer, tol::Real) where {T<:Integer} = Rational{T}(x) rationalize(::Type{T}, x::Integer; tol::Real = 0) where {T<:Integer} = Rational(x, 1) rationalize(x::Integer; kvs...) = Rational(x) From 850e0de8b55a8188dc73e0642670c3d40aa17de9 Mon Sep 17 00:00:00 2001 From: tantheta01 Date: Sun, 19 Dec 2021 17:15:35 +0530 Subject: [PATCH 05/11] Rationalize rational, ignore tolerance --- base/rational.jl | 8 ++++---- test/rational.jl | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/base/rational.jl b/base/rational.jl index 12da98f999149..a479cd462c9e0 100644 --- a/base/rational.jl +++ b/base/rational.jl @@ -218,11 +218,11 @@ rationalize(::Type{T}, x::AbstractFloat; tol::Real = eps(x)) where {T<:Integer} 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...)) -rationalize(::Type{T}, x::Rational, tol::Real) where {T<:Integer} = rationalize(T, float(x), tol)::Rational{T} -rationalize(::Type{T}, x::Rational; tol::Real = zero(x)) where {T<:Integer} = rationalize(T, float(x), tol)::Rational{T} -rationalize(x::Rational{T}; kvs...) where{T} = rationalize(T, x; kvs...) +rationalize(::Type{T}, x::Rational, tol::Real) where {T<:Integer} = Rational{T}(x) +rationalize(x::Rational, tol::Real) where {T<:Integer} = x +rationalize(x::Rational{T}; kvs...) where{T} = x rationalize(::Type{T}, x::Integer, tol::Real) where {T<:Integer} = Rational{T}(x) -rationalize(::Type{T}, x::Integer; tol::Real = 0) where {T<:Integer} = Rational(x, 1) +rationalize(x::Integer, tol::Real) where {T<:Integer} = Rational(x) rationalize(x::Integer; kvs...) = Rational(x) diff --git a/test/rational.jl b/test/rational.jl index 41f37f8267765..7abfa137c7919 100644 --- a/test/rational.jl +++ b/test/rational.jl @@ -33,7 +33,7 @@ using Test @test @inferred(rationalize(Int, 3.0, 0.0)) === 3//1 @test @inferred(rationalize(Int, 3.0, 0)) === 3//1 - @test @inferred(rationalize(Int, 33//100, 0.1)) === 1//3 + @test @inferred(rationalize(Int, 33//100, 0.1)) === 33//100 @test @inferred(rationalize(Int, 3, 0.0)) === 3//1 @test_throws OverflowError rationalize(UInt, -2.0) @test_throws ArgumentError rationalize(Int, big(3.0), -1.) From 4b70c62093429b0924be615923de32fbf3b31e18 Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Thu, 8 Jun 2023 11:27:19 -0400 Subject: [PATCH 06/11] more tests --- test/rational.jl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/rational.jl b/test/rational.jl index d261003f2ecc7..3a4274b64b355 100644 --- a/test/rational.jl +++ b/test/rational.jl @@ -729,3 +729,10 @@ end @test rationalize(1.192 + 2.233im) == 149//125 + 2233//1000*im @test rationalize(Int8, 1.192 + 2.233im) == 118//99 + 67//30*im end +@testset "rationalize(Complex) with tol" begin + # test: rationalize(x::Complex; kvs...) + precise_next = 7205759403792795//72057594037927936 + @assert Float64(precise_next) == nextfloat(0.1) + @test rationalize(nextfloat(0.1) * im; tol=0) == precise_next * im + @test rationalize(0.1im; tol=eps(0.1)) == rationalize(0.1im) +end From 797f27b2c9a8a33e3bf24139e378308376ad0487 Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Fri, 9 Jun 2023 09:51:29 -0400 Subject: [PATCH 07/11] fix overflow and unbound type param. --- base/rational.jl | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/base/rational.jl b/base/rational.jl index b8877e197462e..6b1cc7025ece3 100644 --- a/base/rational.jl +++ b/base/rational.jl @@ -173,7 +173,7 @@ julia> typeof(numerator(a)) BigInt ``` """ -function rationalize(::Type{T}, x::AbstractFloat, tol::Real) where T<:Integer +function rationalize(::Type{T}, x::Union{AbstractFloat, Rational}, tol::Real) where T<:Integer if tol < 0 throw(ArgumentError("negative tolerance $tol")) end @@ -233,17 +233,20 @@ function rationalize(::Type{T}, x::AbstractFloat, tol::Real) where T<:Integer return p // q end end -rationalize(::Type{T}, x::AbstractFloat; tol::Real = eps(x)) where {T<:Integer} = rationalize(T, x, tol)::Rational{T} +rationalize(::Type{T}, x::AbstractFloat; tol::Real = eps(x)) where {T<:Integer} = rationalize(T, x, tol) 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(::Type{T}, x::Complex; kvs...) where {T<:Integer} = Complex(rationalize(T, x.re; kvs...), rationalize(T, x.im; kvs...)) rationalize(x::Complex; kvs...) = Complex(rationalize(Int, x.re; kvs...), rationalize(Int, x.im; kvs...)) -rationalize(::Type{T}, x::Rational, tol::Real) where {T<:Integer} = Rational{T}(x) -rationalize(x::Rational, tol::Real) where {T<:Integer} = x -rationalize(x::Rational{T}; kvs...) where{T} = x -rationalize(::Type{T}, x::Integer, tol::Real) where {T<:Integer} = Rational{T}(x) -rationalize(x::Integer, tol::Real) where {T<:Integer} = Rational(x) +rationalize(::Type{T}, x::Rational; tol::Real = 0) where {T<:Integer} = rationalize(T, x, tol) +rationalize(x::Rational; kvs...) = x rationalize(x::Integer; kvs...) = Rational(x) - +function rationalize(::Type{T}, x::Integer; kvs...) where {T<:Integer} + if Base.hastypemax(T) # BigInt doesn't + x < typemin(T) && return unafe_rational(-one(T), zero(T)) + x > typemax(T) && return unafe_rational(one(T), zero(T)) + end + return Rational{T}(x) +end """ From af59db97b62e675fd18183f7e2af8e16cfc3c16c Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Fri, 9 Jun 2023 11:58:20 -0400 Subject: [PATCH 08/11] fix tests --- test/rational.jl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/rational.jl b/test/rational.jl index 3a4274b64b355..522c61415c808 100644 --- a/test/rational.jl +++ b/test/rational.jl @@ -33,8 +33,11 @@ using Test @test @inferred(rationalize(Int, 3.0, 0.0)) === 3//1 @test @inferred(rationalize(Int, 3.0, 0)) === 3//1 - @test @inferred(rationalize(Int, 33//100, 0.1)) === 33//100 - @test @inferred(rationalize(Int, 3, 0.0)) === 3//1 + @test @inferred(rationalize(Int, 33//100; tol=0.1)) === 33//100 + @test @inferred(rationalize(Int, 3; tol=0.0)) === 3//1 + @test @inferred(rationalize(Int8, 1000//333)) === 3//1 + @test @inferred(rationalize(Int8, 1000//3)) === 1//0 + @test @inferred(rationalize(Int8, 1000)) === 1//0 @test_throws OverflowError rationalize(UInt, -2.0) @test_throws ArgumentError rationalize(Int, big(3.0), -1.) # issue 26823 From 0f8368d2bcf4aa3c26f989ea26946b4880bee301 Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Mon, 12 Jun 2023 09:07:55 -0400 Subject: [PATCH 09/11] typo --- base/rational.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base/rational.jl b/base/rational.jl index 6b1cc7025ece3..baca2397c42ff 100644 --- a/base/rational.jl +++ b/base/rational.jl @@ -242,8 +242,8 @@ rationalize(x::Rational; kvs...) = x rationalize(x::Integer; kvs...) = Rational(x) function rationalize(::Type{T}, x::Integer; kvs...) where {T<:Integer} if Base.hastypemax(T) # BigInt doesn't - x < typemin(T) && return unafe_rational(-one(T), zero(T)) - x > typemax(T) && return unafe_rational(one(T), zero(T)) + x < typemin(T) && return unsafe_rational(-one(T), zero(T)) + x > typemax(T) && return unsafe_rational(one(T), zero(T)) end return Rational{T}(x) end From e6803086cf263a1b5c924c1a3559a5971b15dce8 Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Mon, 12 Jun 2023 15:19:41 -0400 Subject: [PATCH 10/11] fix test --- test/rational.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/rational.jl b/test/rational.jl index 522c61415c808..3769151037a67 100644 --- a/test/rational.jl +++ b/test/rational.jl @@ -35,9 +35,9 @@ using Test @test @inferred(rationalize(Int, 3.0, 0)) === 3//1 @test @inferred(rationalize(Int, 33//100; tol=0.1)) === 33//100 @test @inferred(rationalize(Int, 3; tol=0.0)) === 3//1 - @test @inferred(rationalize(Int8, 1000//333)) === 3//1 - @test @inferred(rationalize(Int8, 1000//3)) === 1//0 - @test @inferred(rationalize(Int8, 1000)) === 1//0 + @test @inferred(rationalize(Int8, 1000//333)) === Rational{Int8}(3//1) + @test @inferred(rationalize(Int8, 1000//3)) === Rational{Int8}(1//0) + @test @inferred(rationalize(Int8, 1000)) === Rational{Int8}(1//0) @test_throws OverflowError rationalize(UInt, -2.0) @test_throws ArgumentError rationalize(Int, big(3.0), -1.) # issue 26823 From ff0e53df02ac82ce54aec0c4368f232e9815f6b1 Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Mon, 12 Jun 2023 20:57:37 -0400 Subject: [PATCH 11/11] Update rational.jl --- test/rational.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/rational.jl b/test/rational.jl index 3769151037a67..0a2501c066052 100644 --- a/test/rational.jl +++ b/test/rational.jl @@ -33,7 +33,7 @@ using Test @test @inferred(rationalize(Int, 3.0, 0.0)) === 3//1 @test @inferred(rationalize(Int, 3.0, 0)) === 3//1 - @test @inferred(rationalize(Int, 33//100; tol=0.1)) === 33//100 + @test @inferred(rationalize(Int, 33//100; tol=0.1)) === 1//3 # because tol @test @inferred(rationalize(Int, 3; tol=0.0)) === 3//1 @test @inferred(rationalize(Int8, 1000//333)) === Rational{Int8}(3//1) @test @inferred(rationalize(Int8, 1000//3)) === Rational{Int8}(1//0)