Reputation: 73
I'm not sure if I explain my question clearly in title, basically I need a floor/ceil function like this:
sub ceil($num)
ceil(120) = 200
ceil(12) = 20
ceil(1.2) = 2
ceil(0.12) = 0.2
ceil(0.012) = 0.02
ceil(0.00000012) = 0.0000002
same apply to negative number (negative sign on both input and output)
thanks!
Upvotes: 2
Views: 173
Reputation: 26121
sub floor {
my $a = shift;
$a =~ s/([1-9])(\d*)(?:\.\d*)?/$1.("0"x length($2))/e;
0 + $a;
}
sub ceil {
my $a = shift;
my $f = floor($a);
$f =~ s/([1-9])/1+$1/e if abs($a) > abs($f);
0 + $f;
}
And test:
$ perl -E'sub floor {my $a = shift; $a=~s/([1-9])(\d*)(?:\.\d*)?/$1.("0"x length($2))/e; 0+$a} sub ceil {my $a = shift;my $f = floor($a); $f=~s/([1-9])/1+$1/e if abs($a) > abs($f); 0+$f} printf "%10g %10g %10g\n", $_, floor($_), ceil($_) for (120, 12, 1.2, 0.12, 0.012, 200, 20, 0.2, -120, -12, -0.12, -0.2,0, 1.2e12, -1.2e-12)'
120 100 200
12 10 20
1.2 1 2
0.12 0.1 0.2
0.012 0.01 0.02
200 200 200
20 20 20
0.2 0.2 0.2
-120 -100 -200
-12 -10 -20
-0.12 -0.1 -0.2
-0.2 -0.2 -0.2
0 0 0
1.2e+12 1e+12 2e+12
-1.2e-12 -1e-12 -2e-12
Upvotes: 3
Reputation: 1487
This might work? I haven't tested it, but I think the logic is there.
Step 1 we find the nearest power of 10 (assign that to "$base")
Step 2 we determine if $num is a cleanly divisble by this base
Step 2.1 if it is, return that
Step 2.2 if it is not, subtract the modulo and add 1
$base = 10*floor(log($num,10));
return ($num % $base)?($num - ($num%$base) + 1):$num;
Math isn't my strongest thing so there could be a better way to go
Upvotes: 1