Skip to content

Commit 05137bc

Browse files
committed
Revise limit testsets
1 parent fa45e36 commit 05137bc

File tree

1 file changed

+120
-140
lines changed

1 file changed

+120
-140
lines changed

test/runtests.jl

Lines changed: 120 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -100,42 +100,37 @@ end
100100
end
101101
end
102102

103-
@testset "limits" begin
104-
for T in CONTAINER_TYPES
105-
f = FixedPointDecimals.max_exp10(T) + 1
106-
powt = FixedPointDecimals.coefficient(FD{T,f})
107-
108-
# ideally we would just use `typemax(T)` but due to precision issues with
109-
# floating-point its possible the closest float will exceed `typemax(T)`.
110-
# Note: we should be doing `trunc(T, ...)` but truncating a BigFloat can be
111-
# problematic (https://github.com/JuliaLang/julia/issues/21914)
112-
max_int = trunc(BigInt, prevfloat(typemax(T) / powt) * powt)
113-
min_int = trunc(BigInt, nextfloat(typemin(T) / powt) * powt)
114-
@eval begin
115-
@test $max_int <= typemax($T)
116-
@test convert(FD{$T,$f}, $(max_int / powt)).i == $max_int
117-
@test $min_int >= typemin($T)
118-
@test convert(FD{$T,$f}, $(min_int / powt)).i == $min_int
119-
120-
@test_throws InexactError convert(FD{$T,$f}, $T(1))
121-
end
122-
end
103+
@testset "limits of $T" for T in CONTAINER_TYPES
104+
f = FixedPointDecimals.max_exp10(T) + 1
105+
powt = FixedPointDecimals.coefficient(FD{T,f})
123106

124-
for T in CONTAINER_TYPES
125-
f = FixedPointDecimals.max_exp10(T)
126-
powt = FixedPointDecimals.coefficient(FD{T,f})
107+
# ideally we would just use `typemax(T)` but due to precision issues with
108+
# floating-point its possible the closest float will exceed `typemax(T)`.
109+
# Note: we should be doing `trunc(T, ...)` but truncating a BigFloat can be
110+
# problematic (https://github.com/JuliaLang/julia/issues/21914)
111+
max_int = trunc(BigInt, prevfloat(typemax(T) / powt) * powt)
112+
min_int = trunc(BigInt, nextfloat(typemin(T) / powt) * powt)
127113

128-
max_int = typemax(T) ÷ powt * powt
129-
min_int = typemin(T) ÷ powt * powt
114+
@test max_int <= typemax(T)
115+
@test value(convert(FD{T,f}, max_int / powt)) == max_int
116+
@test min_int >= typemin(T)
117+
@test value(convert(FD{T,f}, min_int / powt)) == min_int
130118

131-
@eval begin
132-
@test convert(FD{$T,$f}, $(max_int ÷ powt)) == reinterpret(FD{$T,$f}, $max_int)
133-
@test convert(FD{$T,$f}, $(min_int ÷ powt)) == reinterpret(FD{$T,$f}, $min_int)
119+
@test_throws InexactError convert(FD{T,f}, T(1))
134120

135-
@test_throws InexactError convert(FD{$T,$f}, $(max_int ÷ powt) + $T(1))
136-
@test_throws InexactError convert(FD{$T,$f}, $(min_int ÷ powt) - $T(1)) # Overflows with Unsigned
137-
end
138-
end
121+
# Adjust number of decimal places allowed so we can have `-10 < x < 10` where x is
122+
# a FD{T,f}.
123+
f = FixedPointDecimals.max_exp10(T)
124+
powt = FixedPointDecimals.coefficient(FD{T,f})
125+
126+
max_int = typemax(T) ÷ powt * powt
127+
min_int = typemin(T) ÷ powt * powt
128+
129+
@test convert(FD{T,f}, max_int ÷ powt) == reinterpret(FD{T,f}, max_int)
130+
@test convert(FD{T,f}, min_int ÷ powt) == reinterpret(FD{T,f}, min_int)
131+
132+
@test_throws InexactError convert(FD{T,f}, max_int ÷ powt + T(1))
133+
@test_throws InexactError convert(FD{T,f}, min_int ÷ powt - T(1)) # Overflows with Unsigned
139134
end
140135

141136
@test_throws InexactError convert(FD2, FD4(0.0001))
@@ -255,25 +250,21 @@ end
255250
@test FD{Int8,1}(0.1) * 20 == FD{Int8,1}(2.0)
256251
end
257252

258-
@testset "limits" begin
259-
for T in CONTAINER_TYPES
260-
x = FixedPointDecimals.max_exp10(T)
261-
f = x + 1
262-
263-
@eval begin
264-
scalar = reinterpret(FD{$T,$f}, $T(10)^$x) # 0.1
265-
266-
# Since multiply will round the result we'll make sure our value does not
267-
# always rounds down.
268-
max_int = typemax($T) - (typemax($T) % 10)
269-
min_int = typemin($T) - (typemin($T) % 10)
270-
271-
@test reinterpret(FD{$T,$f}, max_int) * scalar ==
272-
reinterpret(FD{$T,$f}, div(max_int, 10))
273-
@test reinterpret(FD{$T,$f}, min_int) * scalar ==
274-
reinterpret(FD{$T,$f}, div(min_int, 10))
275-
end
276-
end
253+
@testset "limits of $T" for T in CONTAINER_TYPES
254+
x = FixedPointDecimals.max_exp10(T)
255+
f = x + 1
256+
257+
scalar = reinterpret(FD{T,f}, T(10)^x) # 0.1
258+
259+
# Since multiply will round the result we'll make sure our value does not
260+
# always rounds down.
261+
max_int = typemax(T) - (typemax(T) % 10)
262+
min_int = typemin(T) - (typemin(T) % 10)
263+
264+
@test reinterpret(FD{T,f}, max_int) * scalar ==
265+
reinterpret(FD{T,f}, div(max_int, 10))
266+
@test reinterpret(FD{T,f}, min_int) * scalar ==
267+
reinterpret(FD{T,f}, div(min_int, 10))
277268
end
278269
end
279270

@@ -373,32 +364,30 @@ end
373364
@testset "limits" begin
374365
@test_throws InexactError Int8(1) / FD{Int8,2}(0.4)
375366
@test_throws InexactError FD{Int8,2}(1) / FD{Int8,2}(0.4)
367+
end
376368

377-
for T in CONTAINER_TYPES
378-
x = FixedPointDecimals.max_exp10(T)
379-
f = x + 1
380-
381-
scalar = reinterpret(FD{T,f}, T(10)^x) # 0.1
382-
383-
# Since multiply will round the result we'll make sure our value always
384-
# rounds down.
385-
max_int = typemax(T) - (typemax(T) % 10)
386-
min_int = typemin(T) - (typemin(T) % 10)
387-
max_fd = reinterpret(FD{T,f}, max_int)
388-
min_fd = reinterpret(FD{T,f}, min_int)
389-
390-
@eval begin
391-
@test ($max_fd * $scalar) / $scalar == $max_fd
392-
@test ($min_fd * $scalar) / $scalar == $min_fd
393-
@test $max_fd / $T(2) == reinterpret(FD{$T,$f}, div($max_int, 2))
394-
@test $min_fd / $T(2) == reinterpret(FD{$T,$f}, div($min_int, 2))
395-
396-
# Since the precision of `f` doesn't allow us to make a FixedDecimal >= 1
397-
# there is no way testing this function without raising an exception.
398-
$max_fd != 0 && @test_throws InexactError $T(2) / $max_fd
399-
$min_fd != 0 && @test_throws InexactError $T(2) / $min_fd
400-
end
401-
end
369+
@testset "limits of $T" for T in CONTAINER_TYPES
370+
x = FixedPointDecimals.max_exp10(T)
371+
f = x + 1
372+
373+
scalar = reinterpret(FD{T,f}, T(10)^x) # 0.1
374+
375+
# Since multiply will round the result we'll make sure our value always
376+
# rounds down.
377+
max_int = typemax(T) - (typemax(T) % 10)
378+
min_int = typemin(T) - (typemin(T) % 10)
379+
max_fd = reinterpret(FD{T,f}, max_int)
380+
min_fd = reinterpret(FD{T,f}, min_int)
381+
382+
@test (max_fd * scalar) / scalar == max_fd
383+
@test (min_fd * scalar) / scalar == min_fd
384+
@test max_fd / T(2) == reinterpret(FD{T,f}, div(max_int, 2))
385+
@test min_fd / T(2) == reinterpret(FD{T,f}, div(min_int, 2))
386+
387+
# Since the precision of `f` doesn't allow us to make a FixedDecimal >= 1
388+
# there is no way testing this function without raising an exception.
389+
max_fd != 0 && @test_throws InexactError T(2) / max_fd
390+
min_fd != 0 && @test_throws InexactError T(2) / min_fd
402391
end
403392
end
404393

@@ -443,7 +432,7 @@ end
443432
@test x == round(FD2, x)
444433
end
445434

446-
@testset "limits $T" for T in CONTAINER_TYPES
435+
@testset "limits of $T" for T in CONTAINER_TYPES
447436
f = FixedPointDecimals.max_exp10(T) + 1
448437
powt = FixedPointDecimals.coefficient(FD{T,f})
449438

@@ -520,30 +509,26 @@ end
520509
end
521510
end
522511

523-
@testset "limits" begin
524-
for T in CONTAINER_TYPES
525-
f = FixedPointDecimals.max_exp10(T) + 1
526-
@eval begin
527-
powt = FixedPointDecimals.coefficient(FD{$T,$f})
528-
529-
# Ideally we would just use `typemax(T)` but due to precision issues with
530-
# floating-point its possible the closest float will exceed `typemax(T)`.
531-
# Additionally, when the division results in a `BigFloat` we need to first
532-
# truncate to a `BigInt` before we can truncate the type we want.
533-
max_int = $T(trunc(BigInt, prevfloat(typemax($T) / powt) * powt))
534-
min_int = $T(trunc(BigInt, nextfloat(typemin($T) / powt) * powt))
535-
536-
# floating-point inprecision makes it hard to know exactly that value to
537-
# expect. Since we're primarily looking for issues relating to overflow this
538-
# we can have the expected result be a little flexible.
539-
@test value(trunc(FD{$T,$f}, max_int / powt)) in [max_int, max_int - 1]
540-
@test value(trunc(FD{$T,$f}, min_int / powt)) in [min_int, min_int + 1]
541-
542-
# Note: all values `x` in FD{T,f} are -1 < x < 1
543-
@test trunc(reinterpret(FD{$T,$f}, typemax($T))) == zero(FD{$T,$f})
544-
@test trunc(reinterpret(FD{$T,$f}, typemin($T))) == zero(FD{$T,$f})
545-
end
546-
end
512+
@testset "limits of $T" for T in CONTAINER_TYPES
513+
f = FixedPointDecimals.max_exp10(T) + 1
514+
powt = FixedPointDecimals.coefficient(FD{T,f})
515+
516+
# Ideally we would just use `typemax(T)` but due to precision issues with
517+
# floating-point its possible the closest float will exceed `typemax(T)`.
518+
# Additionally, when the division results in a `BigFloat` we need to first
519+
# truncate to a `BigInt` before we can truncate the type we want.
520+
max_int = T(trunc(BigInt, prevfloat(typemax(T) / powt) * powt))
521+
min_int = T(trunc(BigInt, nextfloat(typemin(T) / powt) * powt))
522+
523+
# floating-point inprecision makes it hard to know exactly that value to
524+
# expect. Since we're primarily looking for issues relating to overflow this
525+
# we can have the expected result be a little flexible.
526+
@test value(trunc(FD{T,f}, max_int / powt)) in [max_int, max_int - 1]
527+
@test value(trunc(FD{T,f}, min_int / powt)) in [min_int, min_int + 1]
528+
529+
# Note: all values `x` in FD{T,f} are -1 < x < 1
530+
@test trunc(reinterpret(FD{T,f}, typemax(T))) == zero(FD{T,f})
531+
@test trunc(reinterpret(FD{T,f}, typemin(T))) == zero(FD{T,f})
547532
end
548533
end
549534

@@ -590,42 +575,38 @@ epsi{T}(::Type{T}) = eps(T)
590575
end
591576
end
592577

593-
@testset "limits" begin
594-
for T in CONTAINER_TYPES
595-
f = FixedPointDecimals.max_exp10(T) + 1
596-
@eval begin
597-
powt = FixedPointDecimals.coefficient(FD{$T,$f})
598-
599-
# Ideally we would just use `typemax(T)` but due to precision issues with
600-
# floating-point its possible the closest float will exceed `typemax(T)`.
601-
# Additionally, when the division results in a `BigFloat` we need to first
602-
# truncate to a `BigInt` before we can truncate the type we want.
603-
max_int = $T(trunc(BigInt, prevfloat(typemax($T) / powt) * powt))
604-
min_int = $T(trunc(BigInt, nextfloat(typemin($T) / powt) * powt))
605-
606-
max_dec = max_int / powt
607-
min_dec = min_int / powt
608-
609-
# Note: Using a larger signed type as the max/min values may be at the
610-
# limits and overflow when adding or subtracting 1.
611-
@test value(floor(FD{$T,$f}, max_dec)) in [max_int, max_int - 1]
612-
@test value(floor(FD{$T,$f}, min_dec)) in [min_int, signed(widen(min_int)) - 1]
613-
614-
@test value(ceil(FD{$T,$f}, max_dec)) in [max_int, signed(widen(max_int)) + 1]
615-
@test value(ceil(FD{$T,$f}, min_dec)) in [min_int, min_int + 1]
616-
617-
# Note: all values `x` in FD{T,f} are -1 < x < 1
618-
@test floor(reinterpret(FD{$T,$f}, typemax($T))) == zero(FD{$T,$f})
619-
if $T <: Unsigned
620-
@test floor(reinterpret(FD{$T,$f}, typemin($T))) == zero(FD{$T,$f})
621-
else
622-
@test_throws InexactError floor(reinterpret(FD{$T,$f}, typemin($T)))
623-
end
578+
@testset "limits of $T" for T in CONTAINER_TYPES
579+
f = FixedPointDecimals.max_exp10(T) + 1
580+
powt = FixedPointDecimals.coefficient(FD{T,f})
624581

625-
@test_throws InexactError ceil(reinterpret(FD{$T,$f}, typemax($T)))
626-
@test ceil(reinterpret(FD{$T,$f}, typemin($T))) == zero(FD{$T,$f})
627-
end
582+
# Ideally we would just use `typemax(T)` but due to precision issues with
583+
# floating-point its possible the closest float will exceed `typemax(T)`.
584+
# Additionally, when the division results in a `BigFloat` we need to first
585+
# truncate to a `BigInt` before we can truncate the type we want.
586+
max_int = T(trunc(BigInt, prevfloat(typemax(T) / powt) * powt))
587+
min_int = T(trunc(BigInt, nextfloat(typemin(T) / powt) * powt))
588+
589+
max_dec = max_int / powt
590+
min_dec = min_int / powt
591+
592+
# Note: Using a larger signed type as the max/min values may be at the
593+
# limits and overflow when adding or subtracting 1.
594+
@test value(floor(FD{T,f}, max_dec)) in [max_int, max_int - 1]
595+
@test value(floor(FD{T,f}, min_dec)) in [min_int, signed(widen(min_int)) - 1]
596+
597+
@test value(ceil(FD{T,f}, max_dec)) in [max_int, signed(widen(max_int)) + 1]
598+
@test value(ceil(FD{T,f}, min_dec)) in [min_int, min_int + 1]
599+
600+
# Note: all values `x` in FD{T,f} are -1 < x < 1
601+
@test floor(reinterpret(FD{T,f}, typemax(T))) == zero(FD{T,f})
602+
if T <: Unsigned
603+
@test floor(reinterpret(FD{T,f}, typemin(T))) == zero(FD{T,f})
604+
else
605+
@test_throws InexactError floor(reinterpret(FD{T,f}, typemin(T)))
628606
end
607+
608+
@test_throws InexactError ceil(reinterpret(FD{T,f}, typemax(T)))
609+
@test ceil(reinterpret(FD{T,f}, typemin(T))) == zero(FD{T,f})
629610
end
630611
end
631612

@@ -640,14 +621,13 @@ end
640621

641622
# Displaying a decimal could be incorrect when using a decimal place precision which is
642623
# close to or at the limit for our storage type.
643-
for T in CONTAINER_TYPES
624+
@testset "limits of $T" for T in CONTAINER_TYPES
644625
f = FixedPointDecimals.max_exp10(T) + 1
645626
max_str = "0." * rpad(typemax(T), f, '0')
646627
min_str = (typemin(T) < 0 ? "-" : "") * "0." * rpad(abs(widen(typemin(T))), f, '0')
647-
@eval begin
648-
@test string(reinterpret(FD{$T,$f}, typemax($T))) == $max_str
649-
@test string(reinterpret(FD{$T,$f}, typemin($T))) == $min_str
650-
end
628+
629+
@test string(reinterpret(FD{T,f}, typemax(T))) == max_str
630+
@test string(reinterpret(FD{T,f}, typemin(T))) == min_str
651631
end
652632
end
653633

0 commit comments

Comments
 (0)