Hammy has asked for the wisdom of the Perl Monks concerning the following question:

I have a need to round to the nearest 50. Is there a function out there that will do that (ie. 151 rounds to 200). I have searched the Q&A as well as used Google and I have not noticed anything that rounds other than rounding 1.5 to 2.0. Thanks.

Replies are listed 'Best First'.
Re: Rounding to the nearest 50
by jeffa (Bishop) on Mar 01, 2004 at 14:30 UTC
Re: Rounding to the nearest 50
by Crian (Curate) on Mar 01, 2004 at 14:51 UTC
    First of all, you are not looking for the nearest value. What you need is a customised ceil (see perldoc POSIX).

    In such cases, where you want to look for the "nearest but not smaller then" and your step is not 1, but X (X = 50 in your case), you can do the following:

    use POSIX; sub ceilX ($$); print "$_ -> ", ceilX($_, 50), "\n" for (145..154); sub ceilX ($$) { my $number = shift; my $x = shift; return POSIX::ceil($number / $x) * $x; }


    with the result

    145 -> 150 146 -> 150 147 -> 150 148 -> 150 149 -> 150 150 -> 150 151 -> 200 152 -> 200 153 -> 200 154 -> 200


    Edit: Sorry, I was interrupted while writing this answer, when I started writing, there was no comparable posted.
Re: Rounding to the nearest 50
by Roger (Parson) on Mar 01, 2004 at 14:13 UTC
    for my $n (148..153) { print $n + 50 - $n % 50, "\n"; }
    for my $n (148..153) { print $n, '=>', $n + 49 - ($n - 1) % 50, "\n"; }

    Where  $n + 49 - ($n - 1) % 50 computes the rounding up to the nearest 50.

    Update: Modified the fomula so that 150 will not be rounded to 200.

      your code
      for my $n (148..153) { print $n + 50 - $n % 50, "\n"; }
      does the same error as borisz' original post...

      Update:
      now it's better! :p
Re: Rounding to the nearest 50
by Abigail-II (Bishop) on Mar 01, 2004 at 15:00 UTC
    Considering that sprintf knows how to do rounding, it's just a trivial matter of scaling:
    #!/usr/bin/perl use strict; use warnings; foreach my $n (0, 1, 10, 24, 25, 26, 49, 50, 51, 74, 75, 76) { printf "%3d: %3d\n", $n, 50 * sprintf "%.0f" => $n / 50; } __END__ 0: 0 1: 0 10: 0 24: 0 25: 0 26: 50 49: 50 50: 50 51: 50 74: 50 75: 100 76: 100
    Note the bankers rounding.

    Abigail

      but that is not, what the OP wanted (151->200)
        You're right. He must have another definition of 'nearest' than I have.

        Abigail

Re: Rounding to the nearest 50
by borisz (Canon) on Mar 01, 2004 at 14:13 UTC
    for positive integers try
    $x = 151; print (int(( $x + 50 -1 ) / 50) * 50);
    Update: As esskar pointed out I missed a -1.
    Boris
      well... but this way, setting $x = 250 will result in 300... but this is not what he wants
Re: Rounding to the nearest 50
by exussum0 (Vicar) on Mar 01, 2004 at 14:17 UTC
    $x = 1; $y = int( $x / 50 ) * 50; if( $y == $x ){ print $x } else { print $y+50 };
    Doesn't work on negative numbers between -49 and -1, but if you are dealing with currency or something, it doesn't matter. :) Working on the -49 to -1 range now.
Re: Rounding to the nearest 50
by kesterkester (Hermit) on Mar 01, 2004 at 14:45 UTC
    Another technique:

    sub round_to_n { my $val = shift () || 0; my $num = shift () || 5; $val = sprintf ( "%d", 0.5 + $val / $num ); my $ret = $num * $val; return $ret; }