This answer by
Roy Johnson improved
this answer by
wrvhage by dealing with negative numbers. This answer adds an improvement to handle the case where decimal places is zero, i.e. by not including the hanging decimal point, e.g. "10.1" rounded to zero places would become "10." instead of "10". Any other changes are just rearrangement of the code.
sub stround
{
my ($n, $places) = @_;
my $abs = abs $n;
my $val = substr($abs + ('0.' . '0' x $places . '5'),
0,
length(int($abs)) +
(($places > 0) ? $places + 1 : 0)
);
($n < 0) ? "-" . $val : $val;
}