File Coverage

blib/lib/Number/Format/Metric.pm
Criterion Covered Total %
statement 36 52 69.2
branch 22 58 37.9
condition 16 38 42.1
subroutine 7 7 100.0
pod 1 1 100.0
total 82 156 52.5


line stmt bran cond sub pod time code
1             package Number::Format::Metric;
2              
3 1     1   528 use 5.010001;
  1         8  
4 1     1   505 use locale;
  1         625  
  1         5  
5 1     1   38 use strict;
  1         2  
  1         18  
6 1     1   564 use utf8;
  1         14  
  1         5  
7 1     1   30 use warnings;
  1         2  
  1         29  
8              
9 1     1   4 use Exporter qw(import);
  1         2  
  1         526  
10              
11             our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
12             our $DATE = '2023-02-12'; # DATE
13             our $DIST = 'Number-Format-Metric'; # DIST
14             our $VERSION = '0.601'; # VERSION
15              
16             our @EXPORT_OK = qw(
17             format_metric
18             );
19              
20             sub format_metric {
21 7     7 1 1338 my ($num, $opts) = @_;
22 7   50     19 $opts //= {};
23 7   100     25 $opts->{base} //= 2;
24              
25 7   100     23 my $im = $opts->{i_mark} // 1;
26 7         12 my $base0 = $opts->{base};
27 7 100       19 my $base = $base0 == 2 ? 1024 : 1000;
28              
29 7         18 my $rank;
30             my $prefix;
31 7 50       18 if ($num == 0) {
32 0         0 $rank = 0;
33 0         0 $prefix = "";
34             } else {
35 7         42 $rank = int(log(abs($num))/log($base));
36 7 100 100     60 if ($rank == 0 && abs($num) >= 1) { $prefix = "" }
  2 100       6  
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
37 2 100 66     20 elsif ($rank == 1) { $prefix = $im && $base0==10 ? "ki" : "k" } # kilo
38 0 0 0     0 elsif ($rank == 2) { $prefix = $im && $base0==10 ? "Mi" : "M" } # mega
39 1 50 33     8 elsif ($rank == 3) { $prefix = $im && $base0==10 ? "Gi" : "G" } # giga
40 0 0 0     0 elsif ($rank == 4) { $prefix = $im && $base0==10 ? "Ti" : "T" } # tera
41 0 0 0     0 elsif ($rank == 5) { $prefix = $im && $base0==10 ? "Pi" : "P" } # peta
42 0 0 0     0 elsif ($rank >= 8) { $prefix = $im && $base0==10 ? "Yi" : "Y" } # yotta
43 0 0 0     0 elsif ($rank == 7) { $prefix = $im && $base0==10 ? "Zi" : "Z" } # zetta
44 0 0 0     0 elsif ($rank == 6) { $prefix = $im && $base0==10 ? "Ei" : "E" } # exa
45 2         6 elsif ($rank == 0) { $prefix = "m" } # milli
46 0         0 elsif ($rank == -1) { $prefix = "μ" } # micro
47 0         0 elsif ($rank == -2) { $prefix = "n" } # nano
48 0         0 elsif ($rank == -3) { $prefix = "p" } # pico
49 0         0 elsif ($rank == -4) { $prefix = "f" } # femto
50 0         0 elsif ($rank == -5) { $prefix = "a" } # atto
51 0         0 elsif ($rank == -6) { $prefix = "z" } # zepto
52 0         0 elsif ($rank <= -7) { $prefix = "y" } # yocto
53             }
54              
55 7   100     20 my $prec = $opts->{precision} // 1;
56 7 100 100     34 $num = $num / $base**($rank <= 0 && abs($num) < 1 ? $rank-1 : $rank);
57 7 50       34 if ($opts->{return_array}) {
58 0         0 return [$num, $prefix];
59             } else {
60 7         64 my $snum = sprintf("%.${prec}f", $num);
61 7         52 return $snum . $prefix;
62             }
63             }
64              
65             1;
66             # ABSTRACT: Format number with metric prefix
67              
68             __END__