### Rounding off numbers

by tamaguchi (Pilgrim)
 on Apr 20, 2006 at 14:19 UTC Need Help??

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

How do you do in the easyiest way to round of decimal numbers to the nearest integer? thank you for your help.

Replies are listed 'Best First'.
Re: Rounding off numbers
by Tanalis (Curate) on Apr 20, 2006 at 14:22 UTC
I always liked
```\$int = sprintf "%.0f", \$float;
which rounds things off nicely.
<s>sprintf and printf no longer rounds sometime after Perl 5.8.8. It truncates. </s>

EDIT: I think I may have some bad information, which was corrected later on. If a calculation is done which results in 2.4999999999, sprintf("%.2f",2.49999999) would "round" to 2.49 for some reason, which appears to be truncation, but is actually a different problem. You may not be able to reproduce the problem by typing in 2.4999999. 2.49999999 has to be the result of a calculation.

It truncates.
Does it?
```\$ perl -wE 'printf "%.3f\n", .0009 + \$];'
5.023
```(\$q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord
}map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+\$1,++print+eval\$q,q,a,
Re: Rounding off numbers
by swampyankee (Parson) on Apr 20, 2006 at 14:35 UTC

Or, to avoid sprintf, you could use:

```\$rounded = int(\$unrounded + 0.5);

There are actually defined standards for rounding; to be absolutely pedantic, numbers which are exact odd multiples of ½ (i.e., (2n + 1)⁄/2) should round to the nearest odd number, so 4.5 and 5.5 should both round to 5

salva's post reminded me that my fragment will only work for positive values of \$unrounded. For negative values, one would have to subtract 0.5

emc

"Being forced to write comments actually improves code, because it is easier to fix a crock than to explain it. "
—G. Steele
swampyankee,
There are actually defined standards for rounding; to be absolutely pedantic, numbers which are...

Really? Where? I am not saying that because I don't believe you but because I am only familiar with rounding algorithms - not any standards. Do you have any reference material?

I would have thought any standard would have been referenced in this rounding algorithm article or in the Wikipedia entry.

Cheers - L~R

Try this NIST pdf (although I seem to have reversed their rounding rules, which are "round to even" from the ones I remembered which were "round to odd". Ah, daily my memory more and more remembers a steel sieve).

emc

"Being forced to write comments actually improves code, because it is easier to fix a crock than to explain it. "
—G. Steele
```(2*4.5+1)/2=5
(2*5.5+1)/2=6

so I tried:

```(2*int(4.5)+1)/2=4.5
(2*int(5.5)+1)/2=5.5

so then I tried:

```int(2*4.5+1)/2=5
int(2*5.5+1)/2=6

how's that equation and reasoning again? please verify, thanks. and needing a standard rounding algorithm. I am unsure now what's really correct that you've given.

Hello jmichae3, and welcome to the Monastery!

As swampyankee said, int(\$x + 0.5) correctly rounds \$x to an integer, provided that \$x is non-negative.

So, for example, if you have 2 * 4.5 and want to make sure this comes out to 9, use:

```19:27 >perl -wE "my \$x = 2 * 4.5; my \$y = int(\$x + 0.5); say \$y;"
9

19:28 >

This is useful, because for some values (and on some machines), a calculation like 2 * 4.5 might come out as 8.99999999998. But with the formula: add 0.5 and truncate, that’s OK now:

```19:28 >perl -wE "my \$x = 8.99999999998; my \$y = int(\$x + 0.5); say \$y;
+"
9

19:30 >

Hope that helps,

 Athanasius <°(((>< contra mundum Iustus alius egestas vitae, eros Piratica,

Re: Rounding off numbers
by salva (Canon) on Apr 20, 2006 at 14:29 UTC
```use POSIX 'floor';

sub round {
my \$x = shift;
floor(\$x + 0.5);
}

You can use int instead of POSIX::floor if you don't need to round negative numbers. Anyway, read the docs for the int operator in perlfunc man page.

.. though it's important to remember that simply casting a float to an int, thus:
```my \$float = 2.744;
my \$int   = int \$float;
results in the decimal part of the number simply being truncated, giving an integer value with the above example of 2, not 3, which is possibly not what's expected.

Update: Although, of course, adding the 0.5 to the number solves the problem nicely. Didn't see that in the post until just now ..

Adding 0.5 before the int, as in the above example, solves that.
Re: Rounding off numbers
by Roy Johnson (Monsignor) on Apr 20, 2006 at 17:05 UTC
Re: Rounding off numbers
by johngg (Canon) on Apr 20, 2006 at 15:15 UTC
I knocked up a module, probably my first ever, to do rounding. I used POSIX::ceil() and POSIX::floor() to a recipe I saw in a C text book. Written before I knew about strict and warnings, I'm afraid; I'll have to revisit it one day.

```package Rounders;
use Exporter;
@ISA = ('Exporter');
@EXPORT = qw(rndZero rndPlaces);
use Carp;
use POSIX qw(ceil floor pow);

sub rndZero
{
my(\$val) = shift;
my \$rounded = \$val < 0 ?
POSIX::ceil(\$val - 0.5) : POSIX::floor(\$val + 0.5);
return \$rounded;
}

sub rndPlaces
{
my(\$val, \$places) = @_;
my \$rounded = rndZero(\$val * POSIX::pow(10.0, \$places)) /
POSIX::pow(10.0, \$places);
return \$rounded;
}

1;

Calling like this

```\$toNearest100 = rndPlaces(1234.56, -2);

would result in \$toNearest100 getting a value of 1200.

Cheers,

JohnGG

Create A New User
Node Status?
node history
Node Type: perlquestion [id://544606]
Approved by Tanalis
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (4)
As of 2021-01-24 13:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
The STEM quote I most wish I'd made is:

Results (262 votes). Check out past polls.

Notices?