The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
# from the article text
# http://www.pldesignline.com/howto/showArticle.jhtml?articleID=175801189
is(round_half_up_symmetric(3.5), 4);
is(round_half_up_symmetric(-3.5), -4);
is(round_half_up_asymmetric(3.5), 4);
is(round_half_up_asymmetric(-3.5), -3);

is(round_half_down_symmetric(3.5), 3);
is(round_half_down_symmetric(-3.5), -3);
is(round_half_down_asymmetric(3.5), 3);
is(round_half_down_asymmetric(-3.5), -4);

is(round_half_even(3.5), 4);
is(round_half_even(4.5), 4);
is(round_half_even(-3.5), -4);
is(round_half_even(-4.5), -4);

is(round_half_odd(3.5), 3);
is(round_half_odd(4.5), 5);
is(round_half_odd(-3.5), -3);
is(round_half_odd(-4.5), -5);

is(round_alternate(3.5), 4, 'alternate: first round up');
is(round_alternate(3.5), 3, 'alternate: then round down');
is(round_alternate(3.5), 4, 'alternate: then round up');
is(round_alternate(3.5), 3, 'alternate: then round down');
is(round_alternate(3.5), 4, 'alternate: then round up');
is(round_alternate(3.5), 3, 'alternate: then round down');

# FIXME
# how do I reset the state $round_up variable?
# is(round_alternate(-3.5), -4, 'alternate with neg: first round up');
# is(round_alternate(-3.5), -3, 'alternate with neg: then round down');
# is(round_alternate(-3.5), -4, 'alternate with neg: then round up');
# is(round_alternate(-3.5), -3, 'alternate with neg: then round down');
# is(round_alternate(-3.5), -4, 'alternate with neg: then round up');
# is(round_alternate(-3.5), -3, 'alternate with neg: then round down');

is(round_random(3.5), any(3,4));
is(round_random(4.5), any(4,5));
is(round_random(5.5), any(5,6));
is(round_random(6.5), any(6,7));
is(round_random(7.5), any(7,8));
is(round_random(8.5), any(8,9));

is(round_ceiling(3.0), 3);
is(round_ceiling(3.1), 4);
is(round_ceiling(3.2), 4);
is(round_ceiling(3.3), 4);
is(round_ceiling(3.4), 4);
is(round_ceiling(3.5), 4);
is(round_ceiling(3.6), 4);
is(round_ceiling(3.7), 4);
is(round_ceiling(3.8), 4);
is(round_ceiling(3.9), 4);
is(round_ceiling(-3.0), -3);
is(round_ceiling(-3.1), -3);
is(round_ceiling(-3.2), -3);
is(round_ceiling(-3.3), -3);
is(round_ceiling(-3.4), -3);
is(round_ceiling(-3.5), -3);
is(round_ceiling(-3.6), -3);
is(round_ceiling(-3.7), -3);
is(round_ceiling(-3.8), -3);
is(round_ceiling(-3.9), -3);

is(round_floor(-3.0), -3);
is(round_floor(-3.1), -4);
is(round_floor(-3.2), -4);
is(round_floor(-3.3), -4);
is(round_floor(-3.4), -4);
is(round_floor(-3.5), -4);
is(round_floor(-3.6), -4);
is(round_floor(-3.7), -4);
is(round_floor(-3.8), -4);
is(round_floor(-3.9), -4);
is(round_floor(3.0), 3);
is(round_floor(3.1), 3);
is(round_floor(3.2), 3);
is(round_floor(3.3), 3);
is(round_floor(3.4), 3);
is(round_floor(3.5), 3);
is(round_floor(3.6), 3);
is(round_floor(3.7), 3);
is(round_floor(3.8), 3);
is(round_floor(3.9), 3);

is(round_toward_zero(3.1), 3);
is(round_toward_zero(3.2), 3);
is(round_toward_zero(3.3), 3);
is(round_toward_zero(3.4), 3);
is(round_toward_zero(3.5), 3);
is(round_toward_zero(3.6), 3);
is(round_toward_zero(3.7), 3);
is(round_toward_zero(3.8), 3);
is(round_toward_zero(3.9), 3);
is(round_toward_zero(-3.1), -3);
is(round_toward_zero(-3.2), -3);
is(round_toward_zero(-3.3), -3);
is(round_toward_zero(-3.4), -3);
is(round_toward_zero(-3.5), -3);
is(round_toward_zero(-3.6), -3);
is(round_toward_zero(-3.7), -3);
is(round_toward_zero(-3.8), -3);
is(round_toward_zero(-3.9), -3);

is(round_away_from_zero(3.1), 4);
is(round_away_from_zero(3.2), 4);
is(round_away_from_zero(3.3), 4);
is(round_away_from_zero(3.4), 4);
is(round_away_from_zero(3.5), 4);
is(round_away_from_zero(3.6), 4);
is(round_away_from_zero(3.7), 4);
is(round_away_from_zero(3.8), 4);
is(round_away_from_zero(3.9), 4);
is(round_away_from_zero(-3.1), -4);
is(round_away_from_zero(-3.2), -4);
is(round_away_from_zero(-3.3), -4);
is(round_away_from_zero(-3.4), -4);
is(round_away_from_zero(-3.5), -4);
is(round_away_from_zero(-3.6), -4);
is(round_away_from_zero(-3.7), -4);
is(round_away_from_zero(-3.8), -4);
is(round_away_from_zero(-3.9), -4);

is(sign(3.0), 1);
is(sign(0.0), 0);
is(sign(-3.0), -1);

# from the table
# http://i.cmpnet.com/pldesignline/2006/01/max-round-tab01.gif

is(round_half_up_symmetric(3.0), +3);
is(round_half_up_symmetric(3.1), +3);
is(round_half_up_symmetric(3.4), +3);
is(round_half_up_symmetric(3.5), +4);
is(round_half_up_symmetric(3.6), +4);
is(round_half_up_symmetric(3.9), +4);
is(round_half_up_symmetric(4.0), +4);
is(round_half_up_symmetric(4.1), +4);
is(round_half_up_symmetric(4.4), +4);
is(round_half_up_symmetric(4.5), +5);
is(round_half_up_symmetric(4.6), +5);
is(round_half_up_symmetric(4.9), +5);
is(round_half_up_symmetric(5.0), +5);
is(round_half_up_symmetric(-3.0), -3);
is(round_half_up_symmetric(-3.1), -3);
is(round_half_up_symmetric(-3.4), -3);
is(round_half_up_symmetric(-3.5), -4);
is(round_half_up_symmetric(-3.6), -4);
is(round_half_up_symmetric(-3.9), -4);
is(round_half_up_symmetric(-4.0), -4);
is(round_half_up_symmetric(-4.1), -4);
is(round_half_up_symmetric(-4.4), -4);
is(round_half_up_symmetric(-4.5), -5);
is(round_half_up_symmetric(-4.6), -5);
is(round_half_up_symmetric(-4.9), -5);
is(round_half_up_symmetric(-5.0), -5);

is(round_half_up_asymmetric(3.0), +3);
is(round_half_up_asymmetric(3.1), +3);
is(round_half_up_asymmetric(3.4), +3);
is(round_half_up_asymmetric(3.5), +4);
is(round_half_up_asymmetric(3.6), +4);
is(round_half_up_asymmetric(3.9), +4);
is(round_half_up_asymmetric(4.0), +4);
is(round_half_up_asymmetric(4.1), +4);
is(round_half_up_asymmetric(4.4), +4);
is(round_half_up_asymmetric(4.5), +5);
is(round_half_up_asymmetric(4.6), +5);
is(round_half_up_asymmetric(4.9), +5);
is(round_half_up_asymmetric(5.0), +5);
is(round_half_up_asymmetric(-3.0), -3);
is(round_half_up_asymmetric(-3.1), -3);
is(round_half_up_asymmetric(-3.4), -3);
is(round_half_up_asymmetric(-3.5), -3);
is(round_half_up_asymmetric(-3.6), -4);
is(round_half_up_asymmetric(-3.9), -4);
is(round_half_up_asymmetric(-4.0), -4);
is(round_half_up_asymmetric(-4.1), -4);
is(round_half_up_asymmetric(-4.4), -4);
is(round_half_up_asymmetric(-4.5), -4);
is(round_half_up_asymmetric(-4.6), -5);
is(round_half_up_asymmetric(-4.9), -5);
is(round_half_up_asymmetric(-5.0), -5);

is(round_half_down_symmetric(3.0), +3);
is(round_half_down_symmetric(3.1), +3);
is(round_half_down_symmetric(3.4), +3);
is(round_half_down_symmetric(3.5), +3);
is(round_half_down_symmetric(3.6), +4);
is(round_half_down_symmetric(3.9), +4);
is(round_half_down_symmetric(4.0), +4);
is(round_half_down_symmetric(4.1), +4);
is(round_half_down_symmetric(4.4), +4);
is(round_half_down_symmetric(4.5), +4);
is(round_half_down_symmetric(4.6), +5);
is(round_half_down_symmetric(4.9), +5);
is(round_half_down_symmetric(5.0), +5);
is(round_half_down_symmetric(-3.0), -3);
is(round_half_down_symmetric(-3.1), -3);
is(round_half_down_symmetric(-3.4), -3);
is(round_half_down_symmetric(-3.5), -3);
is(round_half_down_symmetric(-3.6), -4);
is(round_half_down_symmetric(-3.9), -4);
is(round_half_down_symmetric(-4.0), -4);
is(round_half_down_symmetric(-4.1), -4);
is(round_half_down_symmetric(-4.4), -4);
is(round_half_down_symmetric(-4.5), -4);
is(round_half_down_symmetric(-4.6), -5);
is(round_half_down_symmetric(-4.9), -5);
is(round_half_down_symmetric(-5.0), -5);

is(round_half_down_asymmetric(3.0), +3);
is(round_half_down_asymmetric(3.1), +3);
is(round_half_down_asymmetric(3.4), +3);
is(round_half_down_asymmetric(3.5), +3);
is(round_half_down_asymmetric(3.6), +4);
is(round_half_down_asymmetric(3.9), +4);
is(round_half_down_asymmetric(4.0), +4);
is(round_half_down_asymmetric(4.1), +4);
is(round_half_down_asymmetric(4.4), +4);
is(round_half_down_asymmetric(4.5), +4);
is(round_half_down_asymmetric(4.6), +5);
is(round_half_down_asymmetric(4.9), +5);
is(round_half_down_asymmetric(5.0), +5);
is(round_half_down_asymmetric(-3.0), -3);
is(round_half_down_asymmetric(-3.1), -3);
is(round_half_down_asymmetric(-3.4), -3);
is(round_half_down_asymmetric(-3.5), -4);
is(round_half_down_asymmetric(-3.6), -4);
is(round_half_down_asymmetric(-3.9), -4);
is(round_half_down_asymmetric(-4.0), -4);
is(round_half_down_asymmetric(-4.1), -4);
is(round_half_down_asymmetric(-4.4), -4);
is(round_half_down_asymmetric(-4.5), -5);
is(round_half_down_asymmetric(-4.6), -5);
is(round_half_down_asymmetric(-4.9), -5);
is(round_half_down_asymmetric(-5.0), -5);

is(round_half_even(3.0), +3);
is(round_half_even(3.1), +3);
is(round_half_even(3.4), +3);
is(round_half_even(3.5), +4);
is(round_half_even(3.6), +4);
is(round_half_even(3.9), +4);
is(round_half_even(4.0), +4);
is(round_half_even(4.1), +4);
is(round_half_even(4.4), +4);
is(round_half_even(4.5), +4);
is(round_half_even(4.6), +5);
is(round_half_even(4.9), +5);
is(round_half_even(5.0), +5);
is(round_half_even(-3.0), -3);
is(round_half_even(-3.1), -3);
is(round_half_even(-3.4), -3);
is(round_half_even(-3.5), -4);
is(round_half_even(-3.6), -4);
is(round_half_even(-3.9), -4);
is(round_half_even(-4.0), -4);
is(round_half_even(-4.1), -4);
is(round_half_even(-4.4), -4);
is(round_half_even(-4.5), -4);
is(round_half_even(-4.6), -5);
is(round_half_even(-4.9), -5);
is(round_half_even(-5.0), -5);

is(round_half_odd(3.0), +3);
is(round_half_odd(3.1), +3);
is(round_half_odd(3.4), +3);
is(round_half_odd(3.5), +3);
is(round_half_odd(3.6), +4);
is(round_half_odd(3.9), +4);
is(round_half_odd(4.0), +4);
is(round_half_odd(4.1), +4);
is(round_half_odd(4.4), +4);
is(round_half_odd(4.5), +5);
is(round_half_odd(4.6), +5);
is(round_half_odd(4.9), +5);
is(round_half_odd(5.0), +5);
is(round_half_odd(-3.0), -3);
is(round_half_odd(-3.1), -3);
is(round_half_odd(-3.4), -3);
is(round_half_odd(-3.5), -3);
is(round_half_odd(-3.6), -4);
is(round_half_odd(-3.9), -4);
is(round_half_odd(-4.0), -4);
is(round_half_odd(-4.1), -4);
is(round_half_odd(-4.4), -4);
is(round_half_odd(-4.5), -5);
is(round_half_odd(-4.6), -5);
is(round_half_odd(-4.9), -5);
is(round_half_odd(-5.0), -5);

is(round_ceiling(3.0), +3);
is(round_ceiling(3.1), +4);
is(round_ceiling(3.4), +4);
is(round_ceiling(3.5), +4);
is(round_ceiling(3.6), +4);
is(round_ceiling(3.9), +4);
is(round_ceiling(4.0), +4);
is(round_ceiling(4.1), +5);
is(round_ceiling(4.4), +5);
is(round_ceiling(4.5), +5);
is(round_ceiling(4.6), +5);
is(round_ceiling(4.9), +5);
is(round_ceiling(5.0), +5);
is(round_ceiling(-3.0), -3);
is(round_ceiling(-3.1), -3);
is(round_ceiling(-3.4), -3);
is(round_ceiling(-3.5), -3);
is(round_ceiling(-3.6), -3);
is(round_ceiling(-3.9), -3);
is(round_ceiling(-4.0), -4);
is(round_ceiling(-4.1), -4);
is(round_ceiling(-4.4), -4);
is(round_ceiling(-4.5), -4);
is(round_ceiling(-4.6), -4);
is(round_ceiling(-4.9), -4);
is(round_ceiling(-5.0), -5);

is(round_floor(3.0), +3);
is(round_floor(3.1), +3);
is(round_floor(3.4), +3);
is(round_floor(3.5), +3);
is(round_floor(3.6), +3);
is(round_floor(3.9), +3);
is(round_floor(4.0), +4);
is(round_floor(4.1), +4);
is(round_floor(4.4), +4);
is(round_floor(4.5), +4);
is(round_floor(4.6), +4);
is(round_floor(4.9), +4);
is(round_floor(5.0), +5);
is(round_floor(-3.0), -3);
is(round_floor(-3.1), -4);
is(round_floor(-3.4), -4);
is(round_floor(-3.5), -4);
is(round_floor(-3.6), -4);
is(round_floor(-3.9), -4);
is(round_floor(-4.0), -4);
is(round_floor(-4.1), -5);
is(round_floor(-4.4), -5);
is(round_floor(-4.5), -5);
is(round_floor(-4.6), -5);
is(round_floor(-4.9), -5);
is(round_floor(-5.0), -5);

is(round_toward_zero(3.0), +3);
is(round_toward_zero(3.1), +3);
is(round_toward_zero(3.4), +3);
is(round_toward_zero(3.5), +3);
is(round_toward_zero(3.6), +3);
is(round_toward_zero(3.9), +3);
is(round_toward_zero(4.0), +4);
is(round_toward_zero(4.1), +4);
is(round_toward_zero(4.4), +4);
is(round_toward_zero(4.5), +4);
is(round_toward_zero(4.6), +4);
is(round_toward_zero(4.9), +4);
is(round_toward_zero(5.0), +5);
is(round_toward_zero(-3.0), -3);
is(round_toward_zero(-3.1), -3);
is(round_toward_zero(-3.4), -3);
is(round_toward_zero(-3.5), -3);
is(round_toward_zero(-3.6), -3);
is(round_toward_zero(-3.9), -3);
is(round_toward_zero(-4.0), -4);
is(round_toward_zero(-4.1), -4);
is(round_toward_zero(-4.4), -4);
is(round_toward_zero(-4.5), -4);
is(round_toward_zero(-4.6), -4);
is(round_toward_zero(-4.9), -4);
is(round_toward_zero(-5.0), -5);

is(round_away_from_zero(3.0), +3);
is(round_away_from_zero(3.1), +4);
is(round_away_from_zero(3.4), +4);
is(round_away_from_zero(3.5), +4);
is(round_away_from_zero(3.6), +4);
is(round_away_from_zero(3.9), +4);
is(round_away_from_zero(4.0), +4);
is(round_away_from_zero(4.1), +5);
is(round_away_from_zero(4.4), +5);
is(round_away_from_zero(4.5), +5);
is(round_away_from_zero(4.6), +5);
is(round_away_from_zero(4.9), +5);
is(round_away_from_zero(5.0), +5);
is(round_away_from_zero(-3.0), -3);
is(round_away_from_zero(-3.1), -4);
is(round_away_from_zero(-3.4), -4);
is(round_away_from_zero(-3.5), -4);
is(round_away_from_zero(-3.6), -4);
is(round_away_from_zero(-3.9), -4);
is(round_away_from_zero(-4.0), -4);
is(round_away_from_zero(-4.1), -5);
is(round_away_from_zero(-4.4), -5);
is(round_away_from_zero(-4.5), -5);
is(round_away_from_zero(-4.6), -5);
is(round_away_from_zero(-4.9), -5);
is(round_away_from_zero(-5.0), -5);