How can I round off the elements in a Perl array to just two decimal places?
I have an array with a few elements:
MSN = 34.3433423432434%
Chrome = 12.4343434353534%
Gtalk = 32.23233543543532% ...
And I'm passing this array as y-axis labels to use with a module called GD::Graph. The problem I am facing right now, is that the number are so big on the graph that they overlap with the adjacent entry and make it unreadable.
Is there a way 开发者_开发问答where I can round off ALL the elements in an array to just 2 decimal places? And make it xx.xx%?
Also, anyone familar with using GD::Graph, do you know how can I increase the text-size on the graph? I can increase Title / Legend size fine, but the actual text as in 'Gtalk' or '32.23233543543532%' is really small and I've tried a lot of the commands from http://search.cpan.org/dist/GDGraph/Graph.pm, but they don't seem to work for me!
From perlfaq4's answer to Does Perl have a round() function? What about ceil() and floor()? Trig functions? :
Remember that int() merely truncates toward 0. For rounding to a certain number of digits, sprintf() or printf() is usually the easiest route.
printf("%.3f", 3.1415926535); # prints 3.142
The POSIX module (part of the standard Perl distribution) implements ceil(), floor(), and a number of other mathematical and trigonometric functions.
use POSIX;
$ceil = ceil(3.5); # 4
$floor = floor(3.5); # 3
In 5.000 to 5.003 perls, trigonometry was done in the Math::Complex module. With 5.004, the Math::Trig module (part of the standard Perl distribution) implements the trigonometric functions. Internally it uses the Math::Complex module and some functions can break out from the real axis into the complex plane, for example the inverse sine of 2.
Rounding in financial applications can have serious implications, and the rounding method used should be specified precisely. In these cases, it probably pays not to trust whichever system rounding is being used by Perl, but to instead implement the rounding function you need yourself.
To see why, notice how you'll still have an issue on half-way-point alternation:
for ($i = 0; $i < 1.01; $i += 0.05) { printf "%.1f ",$i}
0.0 0.1 0.1 0.2 0.2 0.2 0.3 0.3 0.4 0.4 0.5 0.5 0.6 0.7 0.7
0.8 0.8 0.9 0.9 1.0 1.0
Don't blame Perl. It's the same as in C. IEEE says we have to do this. Perl numbers whose absolute values are integers under 2**31 (on 32 bit machines) will work pretty much like mathematical integers. Other numbers are not guaranteed.
#!/usr/bin/perl
use strict; use warnings;
use YAML;
my %x = (
MSN => '34.3433423432434%',
Chrome => '12.4343434353534%',
Gtalk => '32.23233543543532%',
);
for my $x ( values %x ) {
$x =~ s/^(\d+\.\d+)%\z/ sprintf '%.2f%%', $1/e;
}
print Dump \%x;
Output:
Chrome: 12.43% Gtalk: 32.23% MSN: 34.34%
If you want to extract values in a specific order, use a hash slice:
print "@x{ qw( MSN Chrome Gtalk ) }\n";
or, if you just want keys and values to line up in the plot
call:
my $gd = $graph->plot([
[ keys %x ],
[ @x{ keys %x } ],
]) or die $graph->error;
Note: To increase the text size on a GD::Graph
, use a larger font for the element. See Methods for charts with axes.
Using GD::Graph
, you really should not have to modify the values yourself. Just provide the string '.2f%%'
as the argument to y_number_format
.
http://search.cpan.org/dist/Math-Round/Round.pm
Math::Round also works wonders. You can pass it a scalar or a list.
精彩评论