# PERL Round Function

Hey all your PERL junkies like me, I have a present for you. Anyone that has done any coding at all other PERL will know (and miss) the round function that most other languages have built in. For those that may not know, the round function lets you do just that, round a number to the specified digit. So, instead of having to use 3.14159265 as an answer for a particular equation, you could round it to 3.14. Nice, huh?

Well, here is a neato little round function that you can drop into your PERL scripts and call to actually round numbers instead of cutting them off with ceil or cut. Check it out:

```sub round {
my(\$number) = shift;
return int(\$number + .5 * (\$number <=> 0));
}
```

There you go!

**Update**
Thanks to Thierry H. for adding a little mod to the round function allowing you to specify the number of decimals to print. Here is the modified function:

```sub round {
my \$number = shift || 0;
my \$dec = 10 ** (shift || 0);
return int( \$dec * \$number + .5 * (\$number <=> 0)) / \$dec;
}
```

You would call it by giving not only the number to round, but how many numbers to show on the right side of the decimal. It will look like so:

```\$result = round(123.4567,3);
```

This should return 123.457 (the 6 in the third slot gets rounded to 7). There ya go, thanks for the mod Thierry! You can check out Thierry’s site here.

## 8 thoughts on “PERL Round Function”

1. Thierry H. says:

Here is a small enhancement to let a second parameter specifies the # of decimals:

print round(3.14159265,3); # ==> 3.142

sub round {
my \$nombre = shift || 0;
my \$dec = 10 ** (shift || 0);
#return sprintf(“%.\${dec}f”, \$nombre);
return int( \$dec * \$nombre + .5 * (\$nombre 0)) / \$dec;
}

2. Laz says:

Great job, and thanks! I had to figure out the parts removed by WordPress, but once I got that it works like a champ. I will update the post and add your modification.

Thanks again!

3. Tim D. says:

I ran into an example where that round subroutine doesn’t work:

my \$calc = round(1900*18.12895,2)
This returned 34445
The correct value should be 34445.01

This might be due to the fact that int sometimes doesn’t behave as expected (see http://perldoc.perl.org/functions/int.html)
Also, I got strange results from (\$number 0) which is supposed to handle negative numbers.

Here is the modification I came up with:

sub myRound {
my \$number = shift || 0;
my \$places = shift || 0;
my \$dec = 10**\$places;
my \$sign = (\$number >= 0) ? 1 : -1;

\$number = sprintf(”%.0f”,(abs(\$number)*\$dec) +.5);

# return the number with sign and correct decimal places
return \$number * \$sign / \$dec;
}

This gave me the correct result, and it also handles negative numbers:
my \$calc – myRound(1900*-18.12895,2)
returns -34445.01

4. Tim D. says:

Correction for last 2 lines:
my \$calc = myRound(1900*-18.12895,2)
returns -34445.01

5. Tim D. says:

No, this line is wrong:
\$number = sprintf(”%.0f”,(abs(\$number)*\$dec) +.5);

That introduces an error of rounding up when it should be down.
The only way I can com up with for my test case is to replace that line with:
\$number = abs(\$number)*\$dec +.5;
\$number =~ s/\..*\$//;
which instead of using int to truncate which did not work in my test case, treats it as a sting and truncates the decimal that way.

So, the sub now is:
sub myRound {
my \$number = shift || 0;
my \$places = shift || 0;
my \$dec = 10**\$places;
my \$sign = (\$number >= 0) ? 1 : -1;

#\$number = sprintf(”%.0f”,(abs(\$number)*\$dec) +.5);
\$number = abs(\$number)*\$dec +.5;
\$number =~ s/\..*\$//;

# return the number with sign and correct decimal places
return \$number * \$sign / \$dec;
}

6. rodrigo says:

can i round for the next up number?
Eg.:
Number : 16.234
return 17

7. Rich Himpelmann says:

This works great except that numbers that round up do not print any trailing zeros, for example, 164.27984 rounded up to two decimal places returns 164.3, not 164.30. Can someone come up with a fix to make “Round” do this?