|
590 | 590 | @test ismissing(scdm[2])
|
591 | 591 | end
|
592 | 592 |
|
| 593 | +@testset "behavior at signed zero of monotonic floating-point functions mapping zero to zero" begin |
| 594 | + function rounder(rm::RoundingMode) |
| 595 | + function closure(::Type{T}, x::AbstractFloat) where {T <: AbstractFloat} |
| 596 | + round(T, x, rm) |
| 597 | + end |
| 598 | + end |
| 599 | + rounding_modes = ( |
| 600 | + RoundNearest, RoundNearestTiesAway, RoundNearestTiesUp, RoundToZero, RoundFromZero, RoundUp, RoundDown, |
| 601 | + ) |
| 602 | + rounders = map(rounder, rounding_modes) |
| 603 | + @testset "typ: $typ" for typ in (Float16, Float32, Float64, BigFloat) |
| 604 | + (n0, n1) = typ.(0:1) |
| 605 | + rounders_typ = Base.Fix1.(rounders, typ) |
| 606 | + @testset "f: $f" for f in ( |
| 607 | + # all strictly increasing |
| 608 | + identity, deg2rad, rad2deg, cbrt, log1p, expm1, sinh, tanh, asinh, atanh, |
| 609 | + sin, sind, sinpi, tan, tand, tanpi, asin, asind, atan, atand, Base.Fix2(atan, n1), Base.Fix2(atand, n1), |
| 610 | + Base.Fix1(round, typ), Base.Fix1(trunc, typ), +, ∘(-, -), ∘(-, cosc), |
| 611 | + rounders_typ..., |
| 612 | + Base.Fix1(*, n1), Base.Fix2(*, n1), Base.Fix2(/, n1), |
| 613 | + ) |
| 614 | + @testset "s: $s" for s in (-1, 1) |
| 615 | + z = s * n0 |
| 616 | + z::typ |
| 617 | + @test z == f(z)::typ |
| 618 | + @test signbit(z) === signbit(f(z)) |
| 619 | + isbitstype(typ) && |
| 620 | + @test z === @inferred f(z) |
| 621 | + end |
| 622 | + end |
| 623 | + end |
| 624 | +end |
| 625 | + |
593 | 626 | @testset "Integer and Inf args for sinpi/cospi/tanpi/sinc/cosc" begin
|
594 | 627 | for (sinpi, cospi) in ((sinpi, cospi), (x->sincospi(x)[1], x->sincospi(x)[2]))
|
595 | 628 | @test sinpi(1) === 0.0
|
|
0 commit comments