Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

rounding to nearest integer

by dsm (Novice)
on May 11, 2003 at 09:42 UTC ( [id://257206]=perlquestion: print w/replies, xml ) Need Help??

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

Hi Monks,

I need to round a number (such as 7.2342331) to the nearest integer and store that in a variable...any ideas on how to do that? sprintf function?

I don't know if the number needs to be rounded up, or rounded down...

Thanks for your help.

edited: Sun May 11 13:50:19 2003 by jeffa - (title change: was "rounding")

Replies are listed 'Best First'.
Re: rounding to nearest integer
by allolex (Curate) on May 11, 2003 at 09:58 UTC

    perldoc -q round gives us this out of perlfaq4 =). It shows you were on one of the right tracks with printf().

    Does Perl have a round() function? What about ceil() and floor()? Trig functions?

    Remember that int() merely truncates toward 0. For rounding to a certain number of digits, sprintf() or printf() is usually the easiest route.
    printf("%.3f", 3.1415926535); # prints 3.142
    The POSIX module (part of the standard Perl distribution) implements ceil(), floor(), and a number of other mathematical and trigonometric functions.
    use POSIX; $ceil = ceil(3.5); # 4 $floor = floor(3.5); # 3

    --
    Allolex

Re: rounding to nearest integer
by bart (Canon) on May 11, 2003 at 10:03 UTC
    There's an entry in perlfaq4, which comes with perl (try `perldoc perlfaq4` or `perldoc -q round` at the command line prompt): "Does Perl have a round() function? What about ceil() and floor()? Trig functions?" which says to use sprintf. Note that for rounding to the nearest integer, you must use
    sprintf "%.0f", $n
    not
    sprintf "%d", $n
    The latter "rounds towards zero" (AKA "truncate"), just like int does.

    It seems strange to me that POSIX (a standard module) implements ceil() and floor() and zillions of (mathematical and other) functions, doesn't seem to include a round() function.

      It seems strange to me that POSIX (a standard module) implements ceil() and floor() and zillions of (mathematical and other) functions, doesn't seem to include a round() function.

      There are very many different forms of rounding.

(jeffa) Re: rounding to nearest integer
by jeffa (Bishop) on May 11, 2003 at 13:28 UTC
    Another solution is to use Math::Round:
    use warnings; use Math::Round; print round(7.4999999), $/; # yields 7 print round(7.5000000), $/; # yields 8 print nearest(5,7.4), $/; # yields 5 print nearest(5,7.6), $/; # yields 10

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
Re: rounding to nearest integer
by Your Mother (Archbishop) on May 11, 2003 at 11:10 UTC
    IIRC there is a rounding error in s?printf() whereby certain patterns of numbers will round up or down incorrectly (maybe it was system dependant too?). I cannot find the proof/thread/post about it. Anyone know about this who can speak to it?

      The floating-point parts of s?printf() are not implemented directly in perl itself, but handed off to the system library's sprintf() function. As a result, you are at the mercy of any bugs (in rounding or anything else) in the particular version of the system library you (or your customer) are using.

      This is the only part of s?printf() handed off in that way in modern perls. In general, I tend to avoid use of floating-point numbers as far as possible in any application for which precise results are important - often you can model the values you need with integers or rationals, and the Math::Big* family of modules can also help out.

      Hugo
Re: rounding to nearest integer
by BrowserUk (Patriarch) on May 12, 2003 at 07:44 UTC

    sub round { int( $_[0] + ( $_[0] < 0 ? -.5 : .5 ) ); }

    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
Re: rounding to nearest integer
by benn (Vicar) on May 11, 2003 at 10:14 UTC
    There's a Q&A on exactly this here, but my old favourite is $rounded = int($number + 0.5); trashed below - doh! :).

    Cheers,Ben.

        I supposed you could get the int() method to work on negatives by using abs() and some arithmetic with it.

        if ( $value < 0 ) { $rounded = ( int( abs($value) + 0.5) ); $rounded = $rounded - ( $rounded * 2 ); } else { $rounded = int($value + 0.5) }

        or something...

        Seems more complicated than sprintf() =)

        --
        Allolex

        Update: Added closing bracket. (2003-05-15 19:27:26 CEST)

      Note that sprintf will round values exactly halfway between two numbers (0.5 + int $X) up for odd and down for even numbers to avoid a bias toward rounding up.

      Makeshifts last the longest.

        I've heard that proposed many times, but I think it's a fallacy. Should you alternate between rounding N.0 up and down also? N.5 needs to be rounded up, and -N.5 needs to be rounded down.

        For any integer N, for all reals in the range [ N, N+1 ), that is, including N but not quite including N+1, then N+0.5 is in the upper half of the range closest to N+1, while anything less is in the lower half of the range closest to N.

        --
        [ e d @ h a l l e y . c c ]

Re: rounding to nearest integer
by Skeeve (Parson) on May 11, 2003 at 15:43 UTC
    Hmmm... I saw many answers here. But what about the usual way of rounding? $rounded=int($value+0.5);
    Later... What I've learned:
    1) Just because you always did something in a specific way doesn't mean it's correct.
    2) Just becaus a text seems complicated doesn't mean you are free to ignore it
    3) Sometimes you learn it the hard way ;-/
        /me was too embarassed to point it out :)
A reply falls below the community's threshold of quality. You may see it by logging in.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://257206]
Approved by allolex
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (4)
As of 2024-04-23 23:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found