use Test::More tests => 65; BEGIN { use_ok "Data::Float", qw( nextup nextdown nextafter have_signed_zero have_infinite have_nan significand_bits min_finite max_finite max_number float_is_nan pow2 ); } ok nextup( 1) == 1 + pow2(-significand_bits()); ok nextafter(1, +9) == 1 + pow2(-significand_bits()); ok nextdown( 1) == (1-pow2(-significand_bits())) + pow2(-significand_bits()-1); ok nextafter(1, -9) == (1-pow2(-significand_bits())) + pow2(-significand_bits()-1); ok nextup( 3.5) == 3.5 + pow2(1-significand_bits()); ok nextafter(3.5, +9) == 3.5 + pow2(1-significand_bits()); ok nextdown( 3.5) == 3.5 - pow2(1-significand_bits()); ok nextafter(3.5, -9) == 3.5 - pow2(1-significand_bits()); ok nextafter(1.2, 1.2) == 1.2; ok nextup(max_number) == max_number; ok nextdown(-max_number()) == -max_number(); sub zpat($) { my($z) = @_; sprintf("%+.f%+.f%+.f", $z, -$z, - -$z) } my($za, $zb, $r); if(have_signed_zero) { $za = +0.0; $zb = +0.0; $r = nextafter($za, $zb); is zpat($za), "+0-0+0"; is zpat($zb), "+0-0+0"; is zpat($r), "+0-0+0"; ok $r == 0; $za = -0.0; $zb = +0.0; $r = nextafter($za, $zb); is zpat($za), "-0+0-0"; is zpat($zb), "+0-0+0"; is zpat($r), "+0-0+0"; ok $r == 0; $za = +0.0; $zb = -0.0; $r = nextafter($za, $zb); is zpat($za), "+0-0+0"; is zpat($zb), "-0+0-0"; is zpat($r), "-0+0-0"; ok $r == 0; $za = -0.0; $zb = -0.0; $r = nextafter($za, $zb); is zpat($za), "-0+0-0"; is zpat($zb), "-0+0-0"; is zpat($r), "-0+0-0"; ok $r == 0; } else { $za = 0; $zb = 0; $r = nextafter($za, $zb); is zpat($za), "+0+0+0"; is zpat($zb), "+0+0+0"; is zpat($r), "+0+0+0"; ok $r == 0; SKIP: { skip "no signed zero", 12; } } $za = +0.0; ok nextup( $za) == +min_finite(); is zpat($za), zpat(+0.0); $za = +0.0; ok nextafter($za, +9) == +min_finite(); is zpat($za), zpat(+0.0); $za = +0.0; ok nextdown( $za) == -min_finite(); is zpat($za), zpat(+0.0); $za = +0.0; ok nextafter($za, -9) == -min_finite(); is zpat($za), zpat(+0.0); SKIP: { skip "negative zero not available", 8 unless have_signed_zero; $za = -0.0; ok nextup( $za) == +min_finite(); is zpat($za), zpat(-0.0); $za = -0.0; ok nextafter($za, +9) == +min_finite(); is zpat($za), zpat(-0.0); $za = -0.0; ok nextdown( $za) == -min_finite(); is zpat($za), zpat(-0.0); $za = -0.0; ok nextafter($za, -9) == -min_finite(); is zpat($za), zpat(-0.0); } $r = nextup( -min_finite()); is zpat($r), zpat(-0.0); ok $r == 0.0; $r = nextafter(-min_finite(), +9); is zpat($r), zpat(-0.0); ok $r == 0.0; $r = nextdown( +min_finite()); is zpat($r), zpat(+0.0); ok $r == 0.0; $r = nextafter(+min_finite(), -9); is zpat($r), zpat(+0.0); ok $r == 0.0; SKIP: { skip "infinities not available", 8 unless have_infinite; my $pinf = &{"Data::Float::pos_infinity"}; my $ninf = &{"Data::Float::neg_infinity"}; ok nextup( +max_finite()) == $pinf; ok nextafter(+max_finite(), $pinf) == $pinf; ok nextdown( -max_finite()) == $ninf; ok nextafter(-max_finite(), $ninf) == $ninf; ok nextup( $ninf) == -max_finite(); ok nextafter($ninf, $pinf) == -max_finite(); ok nextdown( $pinf) == +max_finite(); ok nextafter($pinf, $ninf) == +max_finite(); } SKIP: { skip "NaN not available", 5 unless have_nan; my $nan = &{"Data::Float::nan"}; ok float_is_nan(nextup($nan)); ok float_is_nan(nextdown($nan)); ok float_is_nan(nextafter($nan, +9)); ok float_is_nan(nextafter(+1.2, $nan)); ok float_is_nan(nextafter($nan, $nan)); }