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

Hi All

I want to round numbers in Perl when printing to output file. I know there's some Math module that I can call, but I'm having trouble with it on my pc.

my $total = 10; my $counter = 3; my $average = ($total/$counter); print Output_file "$average\n"; #do something here

In the end I just want something that prints 3.33, and NOT 3.333333333 Thanks in advance for anyhelp, Kind regards

Replies are listed 'Best First'.
Re: Rounding numbers
by Laurent_R (Canon) on Mar 24, 2014 at 22:00 UTC
    Yeah, sprintf is most probably the right way to go. Just a possible example under the Perl debugger:
    DB<1> print sprintf "%.2f", 10/3; 3.33
    Of course, in that specific example, I could have made it simpler:
    DB<2> printf "%.2f", 10/3 3.33
    Having said that, there are some very rare edge cases where the results are somewhat unexpected because of specific IEEE standard rounding rules. Consider this:
    $ perl -e 'printf "%.2f\n", $_/20 for 1..10' 0.05 0.10 0.15 0.20 0.25 0.30 0.35 0.40 0.45 0.50
    This looks completely fine. Now just round it to one less digit:
    $ perl -e 'printf "%.1f\n", $_/20 for 1..10' 0.1 0.1 0.1 0.2 0.2 0.3 0.3 0.4 0.5 0.5
    This looks a bit awkward, doesn't it? 0.05 and 0.15 are rounded to the same value, which is somewhat contrary to common sense rounding. There are very good reasons why IEEE standards chose that type of rounding, but I had once to write my own custom rounding subroutine for a legacy currency to Euro conversion, because the client would not accept this type of rounding as being correct.
Re: Rounding numbers
by hazylife (Monk) on Mar 24, 2014 at 15:13 UTC
    printf Output_file "%.2f\n", $average;
Re: Rounding numbers
by flexvault (Monsignor) on Mar 24, 2014 at 17:30 UTC
    Just look up 'sprintf'. Lots of answers there!
Re: Rounding numbers
by DrHyde (Prior) on Mar 25, 2014 at 11:23 UTC
    As others have mentioned, printf and sprintf are the functions you want:
    $ perl -E 'say sprintf("%.2f", 5.5678)' 5.57 $ perl -E 'printf("%.2f\n", 5.5678)' 5.57
    If you want to round *all* numbers being written to a file then you may want to write a wrapper around that so you don't have to provide the printf format all the time. One way to do that would be by writing a sub-class of Tie::FileHandle::Base or you could write something based on Tie::STDOUT.
Re: Rounding numbers
by karlgoethebier (Abbot) on Mar 26, 2014 at 10:10 UTC

    Take a look at Math::Round.

    Regards, Karl

    «The Crux of the Biscuit is the Apostrophe»

Re: Rounding numbers
by ww (Archbishop) on Mar 24, 2014 at 15:58 UTC
    #!/usr/bin/perl -w use 5.016; # rounded-1079543.pl - Round to 2 decimal places using regexen # (even though printf/sprintf would be preferred) # update 2: as Laurent_R notes, this is truncation, not ro +unding. # but it is what OP asked for. my $num = 3.333333333; $num =~ /(\d*\.\d{2})/; my $roundednum = $1; say $roundednum; # or my $num2 = 5.5555555; $num2 =~ s/(\d*\.)(\d)(\d).*/$1$2$3/; my $rounded2 = $num2; say $rounded2; =head execution: C:>rounded-1079543.pl 3.33 5.55 =cut

    Reformatted (belatedly): added code tags when the (well-deserved) downvotes accumulated sufficiently to attract my attention.
    Is my impression that answers submitted to the Q&A editors are NOT editable by the author, until approved into public use?
    If so, maybe we should make the input box for Q&A look like (and behave like) those for SOPW, etc.

      It seems to me that your regexes are truncating the numbers, not rounding them.
        Correct!

        That's what OP's examples and problem statement specify, despite misuse of "rounding."


        Questions containing the words "doesn't work" (or their moral equivalent) will usually get a downvote from me unless accompanied by:
        1. code
        2. verbatim error and/or warning messages
        3. a coherent explanation of what "doesn't work actually means.
Re: Rounding numbers
by muneer222 (Initiate) on Mar 25, 2014 at 14:55 UTC
    print int($average * 100)/100, "\n";
      I am sorry, but using the int function does not give you proper rounding.
      $ perl -e 'print int(.678*100)/100;' 0.67
      The result for .678 should be 0,68, not 0.67. The int can certainly be used for building a rounding subroutine, but not with the code presented, it is quite more complicated.
        I understand it is not "proper" rounding. I had the feeling the poster just wanted a quick way to "truncate" the answer to 2 decimal places when printing to an output file.
Re: Rounding numbers
by Anonymous Monk on Mar 25, 2014 at 22:29 UTC
    Be sure to keep in mind that arithmetic is performed using the entire floating point value and that the sum of a column of figures if added with say a pocket calculator might not total up precisely ... it may be off by a few cents. This is normal for all floating-point (and printing with rounding) in all programming languages.
Re: Rounding numbers
by Khen1950fx (Canon) on Mar 27, 2014 at 13:02 UTC
    For me, the easiest way round an average is to use Number::Format:
    #!/usr/bin/perl use strict; use warnings; use Number::Format qw(round); my $total = 1000; my $counter = 3; my $average = ($total/$counter); print "Average ", round($average);