@@ -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
278269end
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
403392end
404393
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
548533end
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
630611end
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
652632end
653633
0 commit comments