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   518 use 5.010001;
  1         8  
4 1     1   453 use locale;
  1         610  
  1         6  
5 1     1   36 use strict;
  1         2  
  1         17  
6 1     1   527 use utf8;
  1         14  
  1         5  
7 1     1   30 use warnings;
  1         2  
  1         28  
8              
9 1     1   5 use Exporter qw(import);
  1         2  
  1         510  
10              
11             our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
12             our $DATE = '2023-02-14'; # DATE
13             our $DIST = 'Number-Format-Metric'; # DIST
14             our $VERSION = '0.602'; # VERSION
15              
16             our @EXPORT_OK = qw(
17             format_metric
18             );
19              
20             sub format_metric {
21 7     7 1 1193 my ($num, $opts) = @_;
22 7   50     19 $opts //= {};
23 7   100     23 $opts->{base} //= 2;
24              
25 7   100     22 my $im = $opts->{i_mark} // 1;
26 7         14 my $base0 = $opts->{base};
27 7 100       15 my $base = $base0 == 2 ? 1024 : 1000;
28              
29 7         13 my $rank;
30             my $prefix;
31 7 50       16 if ($num == 0) {
32 0         0 $rank = 0;
33 0         0 $prefix = "";
34             } else {
35 7         26 $rank = int(log(abs($num))/log($base));
36 7 100 100     43 if ($rank == 0 && abs($num) >= 1) { $prefix = "" }
  2 100       5  
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
37 2 100 66     11 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     7 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         5 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     21 my $prec = $opts->{precision} // 1;
56 7 100 100     29 $num = $num / $base**($rank <= 0 && abs($num) < 1 ? $rank-1 : $rank);
57 7 50       28 if ($opts->{return_array}) {
58 0         0 return [$num, $prefix];
59             } else {
60 7         53 my $snum = sprintf("%.${prec}f", $num);
61 7         41 return $snum . $prefix;
62             }
63             }
64              
65             1;
66             # ABSTRACT: Format number with metric prefix
67              
68             __END__