|
1 | 1 | using FixedPointDecimals
|
2 |
| -import FixedPointDecimals: FD |
| 2 | +import FixedPointDecimals: FD, value |
3 | 3 | using Base.Test
|
4 | 4 | using Compat
|
5 | 5 | import Base.Checked: checked_mul
|
@@ -469,15 +469,18 @@ end
|
469 | 469 | @eval begin
|
470 | 470 | powt = FixedPointDecimals.coefficient(FD{$T,$f})
|
471 | 471 |
|
472 |
| - # ideally we would just use `typemax(T)` but due to precision issues with |
| 472 | + # Ideally we would just use `typemax(T)` but due to precision issues with |
473 | 473 | # floating-point its possible the closest float will exceed `typemax(T)`.
|
474 |
| - max_int = trunc(BigInt, prevfloat(typemax($T) / powt) * powt) |
475 |
| - min_int = trunc(BigInt, nextfloat(typemin($T) / powt) * powt) |
476 |
| - |
477 |
| - # Do not need to know the exact value as we're primarily looking for |
478 |
| - # issues relating to overflow |
479 |
| - @test trunc(FD{$T,$f}, max_int / powt).i in (max_int, max_int - 1) |
480 |
| - @test trunc(FD{$T,$f}, min_int / powt).i in (min_int, min_int + 1) |
| 474 | + # Additionally, when the division results in a `BigFloat` we need to first |
| 475 | + # truncate to a `BigInt` before we can truncate the type we want. |
| 476 | + max_int = $T(trunc(BigInt, prevfloat(typemax($T) / powt) * powt)) |
| 477 | + min_int = $T(trunc(BigInt, nextfloat(typemin($T) / powt) * powt)) |
| 478 | + |
| 479 | + # floating-point inprecision makes it hard to know exactly that value to |
| 480 | + # expect. Since we're primarily looking for issues relating to overflow this |
| 481 | + # we can have the expected result be a little flexible. |
| 482 | + @test value(trunc(FD{$T,$f}, max_int / powt)) in [max_int, max_int - 1] |
| 483 | + @test value(trunc(FD{$T,$f}, min_int / powt)) in [min_int, min_int + 1] |
481 | 484 | end
|
482 | 485 | end
|
483 | 486 | end
|
@@ -532,20 +535,30 @@ epsi{T}(::Type{T}) = eps(T)
|
532 | 535 | @eval begin
|
533 | 536 | powt = FixedPointDecimals.coefficient(FD{$T,$f})
|
534 | 537 |
|
535 |
| - # ideally we would just use `typemax(T)` but due to precision issues with |
| 538 | + # Ideally we would just use `typemax(T)` but due to precision issues with |
536 | 539 | # floating-point its possible the closest float will exceed `typemax(T)`.
|
537 |
| - # Using BigInt as this will avoid overflowing when we do `max_int + 1` and |
538 |
| - # `min_int - 1`. |
539 |
| - max_int = trunc(BigInt, prevfloat(typemax($T) / powt) * powt) |
540 |
| - min_int = trunc(BigInt, nextfloat(typemin($T) / powt) * powt) |
541 |
| - |
542 |
| - # Do not need to know the exact value as we're primarily looking for |
543 |
| - # issues relating to overflow |
544 |
| - @test floor(FD{$T,$f}, max_int / powt).i in (max_int, max_int - 1) |
545 |
| - @test floor(FD{$T,$f}, min_int / powt).i in (min_int, min_int - 1) |
546 |
| - |
547 |
| - @test ceil(FD{$T,$f}, max_int / powt).i in (max_int, max_int + 1) |
548 |
| - @test ceil(FD{$T,$f}, min_int / powt).i in (min_int, min_int + 1) |
| 540 | + # Additionally, when the division results in a `BigFloat` we need to first |
| 541 | + # truncate to a `BigInt` before we can truncate the type we want. |
| 542 | + max_int = $T(trunc(BigInt, prevfloat(typemax($T) / powt) * powt)) |
| 543 | + min_int = $T(trunc(BigInt, nextfloat(typemin($T) / powt) * powt)) |
| 544 | + |
| 545 | + # When working with Int128/UInt128 ceil with max_int will fail without this |
| 546 | + # Fixed in: https://github.com/JuliaLang/julia/pull/19779 |
| 547 | + if VERSION < v"0.6" |
| 548 | + max_dec = /(promote(max_int, powt)...) |
| 549 | + min_dec = /(promote(min_int, powt)...) |
| 550 | + else |
| 551 | + max_dec = max_int / powt |
| 552 | + min_dec = min_dec / powt |
| 553 | + end |
| 554 | + |
| 555 | + # Note: Using a larger signed type as the max/min values may be at the |
| 556 | + # limits and overflow when adding or subtracting 1. |
| 557 | + @test value(floor(FD{$T,$f}, max_dec)) in [max_int, max_int - 1] |
| 558 | + @test value(floor(FD{$T,$f}, min_dec)) in [min_int, signed(widen(min_int)) - 1] |
| 559 | + |
| 560 | + @test value(ceil(FD{$T,$f}, max_dec)) in [max_int, signed(widen(max_int)) + 1] |
| 561 | + @test value(ceil(FD{$T,$f}, min_dec)) in [min_int, min_int + 1] |
549 | 562 | end
|
550 | 563 | end
|
551 | 564 | end
|
|
0 commit comments