Ceil/Floor/Round in Perl

Discussion in 'Perl' started by pradeep, Aug 25, 2009.

  1. pradeep

    pradeep Team Leader

    Joined:
    Apr 4, 2005
    Messages:
    1,645
    Likes Received:
    87
    Trophy Points:
    0
    Occupation:
    Programmer
    Location:
    Kolkata, India
    Home Page:
    http://blog.pradeep.net.in

    Ceil in Perl



    Cieling is basically outputing the next largest integer for an given real number.
    Code:
    ceiling(x) is the smallest integer not less than x
    Ways to do it in Perl, a) using our own logic

    Code:
    my $num = 45.4;
    my $ceil = int($num + 0.99);
    
    b) using POSIX

    Code:
    use POSIX qw/ceil/;
    
    my $num = 45.4;
    my $ceil = ceil($num);
    

    Floor in Perl



    Flooring is outputing the next smallest integer for an given real number.
    Code:
    floor(x) is the largest integer not greater than x
    Ways to do it in Perl, a) using our own logic

    Code:
    my $num = 45.4;
    my $floor = int($num);
    
    b) using POSIX

    Code:
    use POSIX qw/floor/;
    
    my $num = 45.4;
    my $floor = floor($num);
    

    Round in perl



    Rounding is converting any floating-point number to the nearest integer.

    Ways to do it in Perl, a) using our own logic

    Code:
    my $num = 45.4;
    my $round = int($num + 0.5);
    
    b) using Math::Round

    Code:
     use Math::Round qw/round/;
    
    my $num = 45.4;
    my $round = round($num);
    
    It'll be really nice if everyone crontributes to this thread with the equivalent functions in the language they are comfortable with.
     
    shabbir likes this.
  2. asha

    asha New Member

    Joined:
    Nov 9, 2006
    Messages:
    44
    Likes Received:
    2
    Trophy Points:
    0
    Occupation:
    Homemaker
    Location:
    Kolkata
    Home Page:
    http://whatanindianrecipe.com
    Really nice, but the methods using modules is much more reliable I guess.
     
  3. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,341
    Likes Received:
    379
    Trophy Points:
    83
  4. sorin25

    sorin25 New Member

    Joined:
    Jan 3, 2011
    Messages:
    1
    Likes Received:
    0
    Trophy Points:
    0
    God dam, how the fuck are you morons still alive ?

    PHP:
    use POSIX qw/ceil/;
    sub idiot_ceil { return int($_[0] + 0.99) }

    for 
    $i qw/0.0005 -1.4 4.00005/) {
         
    local $,="\t"local $\="\n";
         print 
    $iidiot_ceil($i), ceil($i), (idiot_ceil($i) != ceil($i)) ? " yet again, you are a moron" ".. you got this right genius";
    }
    If you morons have trouble running this, this is the output:
    Code:
    0.0005    0    1     yet again, you are a moron
    -1.4    0    -1     yet again, you are a moron
    4.00005    4    5     yet again, you are a moron
    
    Fuck, and this is a top Google result. Stop publishing this crap before you infect the rest of the planet with your idiocy!
     
  5. stardakev

    stardakev New Member

    Joined:
    Jan 9, 2015
    Messages:
    2
    Likes Received:
    0
    Trophy Points:
    0
    When I don't want the overhead of the full Posix module to implement only the Ceil function, I use this implementation.

    Usage $Result = &Ceil ($Original_Number, $Ceil_Value);

    $Ceil_Value can be any positive, non zero integer.

    Examples
    If rounding up to the nearest dollar $Ceil_Value = 1

    If rounding up to the nearest 5 cents $Ceil_Value = 0.05

    Note, there is no error trapping.

    Code:
     
    sub Ceil {
    
    	my $x = shift;
    
    	my $r = shift;
    
    	my $Len = &decLen($x);
    
    	my $rLen = &decLen($r);
    
    	$Len = $rLen if $rLen > $Len;
    
    	$x = $x * 10**$Len;
    
    	$r = $r * 10**$Len;
    
    	my $ceil = ($x + ((-$x) % $r)) / 10**$Len;
    
    	return $ceil;
    }
    
    sub decLen {    #returns how many digits after the decimal point
    
    	my ($a, $c) = ($_[0] =~ /(\d*).(\d*)/);
    
    	return length $c
    }
    
     
  6. stardakev

    stardakev New Member

    Joined:
    Jan 9, 2015
    Messages:
    2
    Likes Received:
    0
    Trophy Points:
    0
    My bad

    I meant $Ceil_Value can be any positive, non zero value.
     
  7. Scarab

    Scarab New Member

    Joined:
    Jul 2, 2021
    Messages:
    1
    Likes Received:
    1
    Trophy Points:
    3
    Gender:
    Male
    Since this is still a top-result on google, and sorin25 is right (though not too polite or elaborate ;-) ), I thought I'll provide a solution to implement ceil(), floor(), and round() with the Perl-native function int(). Note that int() is a truncating function, and different from floor() for negative numbers. I took a cue from sorin25 and added some vaidation code for the functions.

    Code:
    #!/usr/bin/perl -w
    
    use POSIX qw/ceil floor/;
    use Math::Round qw/round/;
    
    # Rounds up a value, using int() function
    sub my_ceil
    {
        my $t = int($_[0]);
        return ($t != $_[0]) ? ($_[0] < 0) ? $t : $t + 1 : $_[0];
    }
    
    # Rounds down a value, using int() function
    sub my_floor
    {
        return ($_[0] < 0) ? int($_[0]) - 1 : int($_[0]);
    }
    
    # Rounds a value, using int() function
    sub my_round
    {
        return ($_[0] < 0) ? int($_[0] - 0.5) : int($_[0] + 0.5);
    }
    
    # Truncates a value, using ceil() and floor() functions
    sub my_int
    {
        return ($_[0] < 0) ? ceil($_[0]) : floor($_[0]);
    }
    
    for $i ( qw/3 5.5 -3.5 0.0005 -1.4 4.00005 -4.0005 -0.0005/) {
         local $,="\t"; local $\="\n";
         print "int:   ", $i, my_int($i), int($i), (my_int($i) != int($i)) ? "FAIL" : "PASS";
         print "ceil:  ", $i, my_ceil($i), ceil($i), (my_ceil($i) != ceil($i)) ? "FAIL" : "PASS";
         print "floor: ", $i, my_floor($i), floor($i), (my_floor($i) != floor($i)) ? "FAIL" : "PASS";
         print "round: ", $i, my_round($i), round($i), (my_round($i) != round($i)) ? "FAIL" : "PASS";
    }
    
     
    shabbir likes this.

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice