diff --git a/src/TinyHugeNumbers.jl b/src/TinyHugeNumbers.jl index 023f516..5418ae0 100644 --- a/src/TinyHugeNumbers.jl +++ b/src/TinyHugeNumbers.jl @@ -124,8 +124,11 @@ const huge = HugeNumber() # but it cannot be instantiated, this might be useful in situations like `clamp(value, tiny, huge)` # in this case Julia attempts first to promote `tiny` and `huge` to the same type and then # uses the result to promote `value` to the resulting type. However, there is no "common" type for -# both `tiny` and `huge` so we introduce a special structure that will accomodate that +# both `tiny` and `huge` (except for the `Union` but we can't use it either since it introduces ambiguities) +# so we introduce a special structure that will accomodate that # see also: https://github.com/ReactiveBayes/TinyHugeNumbers.jl/issues/3 +# note: as a result, we cannot store `tiny` and `huge` in the same container (e.g. `Array`), +# but `[ 1.0, tiny, huge ]` will work just fine struct PromoteTinyOrHuge PromoteTinyOrHuge() = error("Cannot instantiate an internal structure for promotion.") end diff --git a/test/runtests.jl b/test/runtests.jl index eede59a..3a08cb3 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,6 +1,6 @@ using TinyHugeNumbers, Aqua, Test -Aqua.test_all(TinyHugeNumbers, deps_compat = (; check_extras = false, check_weakdeps = true)) +Aqua.test_all(TinyHugeNumbers, deps_compat=(; check_extras=false, check_weakdeps=true)) @testset "TinyHugeNumbers.jl" begin import TinyHugeNumbers: TinyNumber, HugeNumber @@ -75,9 +75,6 @@ Aqua.test_all(TinyHugeNumbers, deps_compat = (; check_extras = false, check_weak @test @inferred(promote_type(T, HugeNumber, TinyNumber)) == T end - @test_throws "Cannot convert `tiny` to `huge`" [tiny, huge] - @test_throws "Cannot convert `huge` to `tiny`" [huge, tiny] - for a in (1, 1.0, 0, 0.0, 1.0f0, 0.0f0, Int32(0), Int32(1), big"1", big"1.0", big"0", big"0.0") T = typeof(a) for v in Real[tiny, huge] @@ -115,20 +112,40 @@ end @testset "ForwardDiff.jl compatibility" begin import ForwardDiff - + f(x) = clamp(x, tiny, huge) @test @inferred(ForwardDiff.derivative(f, 1.0)) === 1.0 @test @inferred(ForwardDiff.derivative(f, 2.0)) === 1.0 @test @inferred(ForwardDiff.derivative(f, 0.0)) === 0.0 - @test @inferred(ForwardDiff.derivative(f, huge+1.0)) === 0.0 - @test @inferred(ForwardDiff.derivative(f, tiny-1.0)) === 0.0 + @test @inferred(ForwardDiff.derivative(f, huge + 1.0)) === 0.0 + @test @inferred(ForwardDiff.derivative(f, tiny - 1.0)) === 0.0 g(x) = clamp(x^2, tiny, huge) @test @inferred(ForwardDiff.derivative(g, 1.0)) === 2.0 @test @inferred(ForwardDiff.derivative(g, 2.0)) === 4.0 @test @inferred(ForwardDiff.derivative(g, 0.0)) === 0.0 - @test @inferred(ForwardDiff.derivative(g, huge+1.0)) === 0.0 - @test @inferred(ForwardDiff.derivative(g, tiny-1.0)) === 2(tiny-1.0) + @test @inferred(ForwardDiff.derivative(g, huge + 1.0)) === 0.0 + @test @inferred(ForwardDiff.derivative(g, tiny - 1.0)) === 2(tiny - 1.0) +end + +@testset "Storing `tiny` and `huge` in arrays" begin + @static if VERSION >= v"1.10" + @test_throws "Cannot convert `tiny` to `huge`" [tiny, huge] + @test_throws "Cannot convert `huge` to `tiny`" [huge, tiny] + else + @test_throws ErrorException [tiny, huge] + @test_throws ErrorException [huge, tiny] + end + + for a in (1.0, 0.0, 1.0f0, 0.0f0, big"1.0", big"0.0") + @test [a, tiny, huge] == [a, tiny(a), huge(a)] + @test [tiny, a, huge] == [tiny(a), a, huge(a)] + @test [tiny, huge, a] == [tiny(a), huge(a), a] + + @test [a, huge, tiny] == [a, huge(a), tiny(a)] + @test [huge, a, tiny] == [huge(a), a, tiny(a)] + @test [huge, tiny, a] == [huge(a), tiny(a), a] + end end