Re: Best way to round a number.
by BrowserUk (Patriarch) on Oct 25, 2012 at 01:01 UTC
|
If you actually want "the nearest multiple of 5", then:
sub roundToNearest5{
5 * int( ( $_[0] + ( 2 * ( $_[0] <=> 0 ) ) ) / 5 );
}
print "$_: ", roundToNearest5( $_ ) for -18..+18;;
-18: -20
-17: -15
-16: -15
-15: -15
-14: -15
-13: -15
-12: -10
-11: -10
-10: -10
-9: -10
-8: -10
-7: -5
-6: -5
-5: -5
-4: -5
-3: -5
-2: 0
-1: 0
0: 0
1: 0
2: 0
3: 5
4: 5
5: 5
6: 5
7: 5
8: 10
9: 10
10: 10
11: 10
12: 10
13: 15
14: 15
15: 15
16: 15
17: 15
18: 20
With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
RIP Neil Armstrong
codecode | [reply] [d/l] |
Re: Best way to round a number.
by Anonymous Monk on Oct 25, 2012 at 00:06 UTC
|
Why would 33 be rounded down to the nearest lower multiple of 5; and 36 be rounded up to the nearest higher multiple of 5? (Ditto: 33 down to 30; but 3 up to 5?)
| [reply] |
|
|
Alright, forget the multiple of 5 thing, its to the nearest 5 per say; therefore 33, should go to 30 because of the logic on the sample code I gave here, if the last number in this case is 3 (from 33), is less than five it should go to 30. So number 11 should go down to 10, 17 should round up to 20, I hope I am a lil clear on that now, thanks!
| [reply] |
|
|
| [reply] [d/l] |
|
|
How is 33 closer to 30 than to 35?
30 31 32 33 34 35
I count two numbers between 30 and 33, but only one number between 33 and 35. Clearly 33 is closer to 35.
| [reply] |
Re: Best way to round a number.
by ajam (Acolyte) on Oct 25, 2012 at 00:32 UTC
|
It can be done with less division.
Notice 0, 1 and 2 round to 0. While 3 and 4 round up to 5. Using this knowledge, examine the number modulus 5. If its below 3 round down, otherwise round up.
Also I agree with the other comment, your examples are a bit off. For example both 33 and 36 round to 35.
use warnings;
use strict;
sub round5 {
my ($number) = @_;
my $remainder = $number % 5;
if ($remainder < 3) {
return $number - $remainder;
} else {
return $number - $remainder + 5;
}
}
for (0..10) {
print "$_ rounded is " . round5($_) . "\n";
}
| [reply] [d/l] |
Re: Best way to round a number.
by ww (Archbishop) on Oct 25, 2012 at 01:41 UTC
|
Actually, the "best" way to round a number may be as follows:
perl -E "my $num=\"33\"; say \"$num\".'0';"
330
There appears to be some general agreement that any multiple of ten is a "round" number. If that's not a broad enough concensus, try concatenating 2, 3, 4 or 5 zeros.
This solution is scarcely more fatuous than your suggestion that the best way to round a number is "the logic on the sample code...." | [reply] [d/l] |
Re: Best way to round a number.
by CountZero (Bishop) on Oct 25, 2012 at 07:58 UTC
|
Maybe not the "best" way, but very flexible: adjust the %rule hash to change the way the rounding will work based upon the last digit and the regex will do all the work (assuming you feed it a positive integer): use Modern::Perl;
my %rule = (
0 => 0,
1 => -1,
2 => -2,
3 => 2,
4 => 1,
5 => 0,
6 => -1,
7 => -2,
8 => 2,
9 => 1,
);
my @nums = 0..30;
foreach (@nums) {
print "in=$_";
s/(\d*(\d))/$1+$rule{$2}/e;
say "\t rounded=$_";
}
CountZero A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James My blog: Imperial Deltronics
| [reply] [d/l] [select] |
Re: Best way to round a number.
by Marshall (Canon) on Oct 25, 2012 at 05:15 UTC
|
use strict;
use warnings;
my @nums = qw (0 1 4 5 6 11 14 15 16 20 24 25 26 30 34 35 36);
foreach (@nums)
{
print "in=$_\t rounded=", round_nearest5($_), "\n";
}
sub round_nearest5 # for an positive integer numeric value
{
my $in = shift;
my ($last_digit) = $in =~ /(\d)\s*$/;
if ($last_digit <5 and $in >= 10 )
{
$in =~ s/(\d)$/0/;
}
elsif ($last_digit >=5)
{
$in += (10-$last_digit);
}
return $in;
}
__END__
in=0 rounded=0
in=1 rounded=1
in=4 rounded=4
in=5 rounded=10
in=6 rounded=10
in=11 rounded=10
in=14 rounded=10
in=15 rounded=20
in=16 rounded=20
in=20 rounded=20
in=24 rounded=20
in=25 rounded=30
in=26 rounded=30
in=30 rounded=30
in=34 rounded=30
in=35 rounded=40
in=36 rounded=40
| [reply] [d/l] |
Re: Best way to round a number.
by Cristoforo (Curate) on Oct 25, 2012 at 00:41 UTC
|
| [reply] |
Re: Best way to round a number.
by Perlbotics (Archbishop) on Oct 26, 2012 at 21:07 UTC
|
use strict;
use warnings;
sub round5 {
my $num = shift;
return $num+2 - ($num+2) % 5; # <------ TIMTOWTDI ;-)
}
for (0..10) {
printf "%3d -> %3d %3d -> %3d\n",
$_, round5($_), -$_, round5(-$_);
}
__DATA__
0 -> 0 0 -> 0
1 -> 0 -1 -> 0
2 -> 0 -2 -> 0
3 -> 5 -3 -> -5
4 -> 5 -4 -> -5
5 -> 5 -5 -> -5
6 -> 5 -6 -> -5
7 -> 5 -7 -> -5
8 -> 10 -8 -> -10
9 -> 10 -9 -> -10
10 -> 10 -10 -> -10
| [reply] [d/l] |