From 622c39ee9756cc65714ada1476212da924c08dae Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Thu, 2 Sep 2021 10:22:22 +0100 Subject: [PATCH] Support arithmetic with floats and InfiniteCardinal (#14) * Support arithmetic with floats and InfiniteCardinal * one(InfiniteCardinal) * convert to float for RealInfinity, oneunit overrides * increase coverage --- .github/workflows/ci.yml | 2 +- Project.toml | 2 +- src/Infinities.jl | 14 +++++++++++++- src/cardinality.jl | 25 +++++++++++++++++-------- test/runtests.jl | 9 ++++++++- test/test_cardinality.jl | 7 ++++++- 6 files changed, 46 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 57aa118..f206ea3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ jobs: version: - '1.0' - '1' - - '^1.6.0-0' + - '^1.7.0-0' os: - ubuntu-latest - macOS-latest diff --git a/Project.toml b/Project.toml index 4cdb4a6..cf21bab 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "Infinities" uuid = "e1ba4f0e-776d-440f-acd9-e1d2e9742647" authors = ["Sheehan Olver "] -version = "0.1.0" +version = "0.1.1" [compat] julia = "1" diff --git a/src/Infinities.jl b/src/Infinities.jl index 778c1c6..9b1eb4f 100644 --- a/src/Infinities.jl +++ b/src/Infinities.jl @@ -1,6 +1,6 @@ module Infinities -import Base: angle, isone, iszero, isinf, isfinite, abs, one, zero, isless, +import Base: angle, isone, iszero, isinf, isfinite, abs, one, oneunit, zero, isless, +, -, *, ==, <, ≤, >, ≥, fld, cld, div, mod, min, max, sign, signbit, string, show, promote_rule, convert, getindex @@ -42,6 +42,8 @@ sign(y::Infinity) = 1 angle(x::Infinity) = 0 one(::Type{Infinity}) = 1 +oneunit(::Type{Infinity}) = 1 +oneunit(::Infinity) = 1 zero(::Infinity) = 0 isinf(::Infinity) = true @@ -139,6 +141,16 @@ isfinite(::RealInfinity) = false promote_rule(::Type{Infinity}, ::Type{RealInfinity}) = RealInfinity convert(::Type{RealInfinity}, ::Infinity) = RealInfinity(false) +convert(::Type{Float64}, x::RealInfinity) = sign(x)*Inf64 +convert(::Type{Float32}, x::RealInfinity) = sign(x)*Inf32 +convert(::Type{Float16}, x::RealInfinity) = sign(x)*Inf16 +Base.Float64(x::RealInfinity) = convert(Float64, x) +Base.Float32(x::RealInfinity) = convert(Float32, x) +Base.Float16(x::RealInfinity) = convert(Float16, x) +Base.BigFloat(x::RealInfinity) = sign(x)*BigFloat(Inf) +convert(::Type{AF}, x::RealInfinity) where AF<:AbstractFloat = sign(x)*convert(AF, Inf) + + signbit(y::RealInfinity) = y.signbit sign(y::RealInfinity) = 1-2signbit(y) angle(x::RealInfinity) = π*signbit(x) diff --git a/src/cardinality.jl b/src/cardinality.jl index bbfc2dd..6b87b67 100644 --- a/src/cardinality.jl +++ b/src/cardinality.jl @@ -28,7 +28,9 @@ sign(::InfiniteCardinal) = 1 angle(::InfiniteCardinal) = 0 abs(a::InfiniteCardinal) = a zero(::InfiniteCardinal) = 0 -one(::InfiniteCardinal) = 1 +one(::Type{<:InfiniteCardinal}) = 1 +oneunit(::Type{<:InfiniteCardinal}) = 1 +oneunit(::InfiniteCardinal) = 1 isinf(::InfiniteCardinal) = true isfinite(::InfiniteCardinal) = false @@ -153,11 +155,18 @@ end -(::InfiniteCardinal) = -∞ -(x::Integer, ::InfiniteCardinal) = x - ∞ +for op in (:+, :-) + @eval begin + $op(x::Number, ::InfiniteCardinal) = $op(x, ∞) + $op(::InfiniteCardinal, x::Number) = $op(∞, x) + end +end + for OP in (:fld,:cld,:div) - @eval begin - $OP(x::InfiniteCardinal, ::Real) = x - $OP(::InfiniteCardinal, ::InfiniteCardinal) = NotANumber() - end + @eval begin + $OP(x::InfiniteCardinal, ::Real) = x + $OP(::InfiniteCardinal, ::InfiniteCardinal) = NotANumber() + end end div(::T, ::InfiniteCardinal) where T<:Real = zero(T) @@ -205,7 +214,7 @@ Base._unsafe_getindex(::IndexStyle, A::AbstractArray, I::InfiniteCardinal{0}) = # Avoid too-strict restrictions in SubArray function getindex(V::SubArray{T,N}, i1::InfiniteCardinal{0}, I::Integer...) where {T,N} - @boundscheck checkbounds(V, i1, I...) - @inbounds r = V.parent[Base.reindex(V.indices, tuple(i1, I...))...] - r + @boundscheck checkbounds(V, i1, I...) + @inbounds r = V.parent[Base.reindex(V.indices, tuple(i1, I...))...] + r end diff --git a/test/runtests.jl b/test/runtests.jl index 06dd0a4..da26cd9 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -35,7 +35,7 @@ import Infinities: Infinity @test ∞*∞ ≡ ∞ @test ∞ - ∞ isa NotANumber - @test one(∞) ≡ 1 + @test one(∞) ≡ one(Infinity) ≡ oneunit(∞) ≡ oneunit(Infinity) ≡ 1 @test zero(∞) ≡ 0 @test !isone(∞) @@ -191,6 +191,13 @@ import Infinities: Infinity @test max(5, RealInfinity()) ≡ max(RealInfinity(), 5) ≡ RealInfinity() @test max(5, -∞) ≡ max(-∞, 5) ≡ 5 end + + @testset "convert" begin + @test convert(Float64, -∞) ≡ Float64(-∞) ≡ -Inf + @test convert(Float32, -∞) ≡ Float32(-∞) ≡ -Inf32 + @test convert(Float16, -∞) ≡ Float16(-∞) ≡ -Inf16 + @test convert(BigFloat, -∞)::BigFloat == BigFloat(-∞)::BigFloat == -BigFloat(Inf) + end end @testset "ComplexInfinity" begin diff --git a/test/test_cardinality.jl b/test/test_cardinality.jl index 843c170..f0379c7 100644 --- a/test/test_cardinality.jl +++ b/test/test_cardinality.jl @@ -9,7 +9,7 @@ using Infinities, Base64, Base.Checked, Test @test Integer(∞) ≡ convert(Integer,∞) ≡ Integer(ℵ₀) ≡ convert(Integer, ℵ₀) ≡ ℵ₀ @test abs(ℵ₀) ≡ ℵ₀ @test zero(ℵ₀) ≡ 0 - @test one(ℵ₀) ≡ 1 + @test one(ℵ₀) ≡ one(InfiniteCardinal{0}) ≡ oneunit(ℵ₀) ≡ oneunit(InfiniteCardinal{0}) ≡ 1 @test isinf(ℵ₀) && !isfinite(ℵ₀) @test Integer(RealInfinity()) ≡ Integer(ComplexInfinity()) ≡ ℵ₀ @test_throws InexactError Integer(-∞) @@ -94,6 +94,11 @@ using Infinities, Base64, Base.Checked, Test @test 5 * ℵ₀ ≡ ℵ₀ * 5 ≡ ℵ₀ @test 5.0ℵ₀ ≡ ℵ₀*5.0 ≡ RealInfinity() @test_throws ArgumentError (-5) * ℵ₀ + + @test ℵ₀ - 5.1 ≡ ∞ + @test ℵ₀ + 5.1 ≡ ∞ + @test 5.1 + ℵ₀ ≡ ∞ + @test 5.1 - ℵ₀ ≡ -∞ end @testset "fld/cld/div/mod" begin