File Coverage

blib/lib/Lingua/Base/Number/Format/MixWithWords.pm
Criterion Covered Total %
statement 60 60 100.0
branch 21 26 80.7
condition 10 12 83.3
subroutine 8 8 100.0
pod 0 1 0.0
total 99 107 92.5


line stmt bran cond sub pod time code
1             package Lingua::Base::Number::Format::MixWithWords;
2              
3 2     2   31 use 5.010;
  2         6  
  2         80  
4 2     2   10 use strict;
  2         3  
  2         89  
5 2     2   10 use warnings;
  2         4  
  2         73  
6              
7 2     2   1789 use Math::Round qw(nearest);
  2         27647  
  2         155  
8 2     2   3188 use Number::Format;
  2         15337  
  2         124  
9 2     2   20 use POSIX qw(floor ceil log10);
  2         15  
  2         24  
10              
11             our $VERSION = '0.07'; # VERSION
12              
13             our %SPEC;
14              
15             sub new {
16 18     18 0 85 my ($class, %args) = @_;
17 18   100     71 $args{min_fraction} //= 1;
18 18   100     66 $args{min_format} //= 1000000;
19              
20 18 50 33     114 die "Invalid min_fraction, must be 0 < x <= 1"
21             unless $args{min_fraction} > 0 && $args{min_fraction} <= 1;
22 18         104 $args{_nf} = Number::Format->new(
23             THOUSANDS_SEP => $args{thousands_sep},
24             DECIMAL_POINT => $args{decimal_point},
25             );
26 18         5808 $args{powers} = [sort {$a<=>$b} keys %{$args{names}}];
  1407         1540  
  18         166  
27 18         118 bless \%args, $class;
28             }
29              
30             sub _format {
31 18     18   33 my ($self, $num) = @_;
32 18 50       54 return undef unless defined $num;
33              
34 18 100       56 if (defined $self->{num_decimal}) {
35 2         24 $num = nearest(10**-$self->{num_decimal}, $num);
36             }
37 18         49 my ($exp, $mts, $exp_f);
38 18         30 my $anum = abs($num);
39 18 100       39 if ($anum) {
40 17         124 $exp = floor(log10($anum));
41 17         40 $mts = $anum / 10**$exp;
42 17         61 $exp_f = floor(log10($anum/$self->{min_fraction}));
43             } else {
44 1         2 $exp = 0;
45 1         2 $mts = 0;
46 1         1 $exp_f = 0;
47             }
48              
49 18         28 my $p;
50 18         19 my ($res_n, $res_w);
51 18         22 for my $i (0..@{$self->{powers}}-1) {
  18         50  
52 46 100       109 last if $self->{powers}[$i] > $exp_f;
53 28         48 $p = $self->{powers}[$i];
54             }
55 18 100 100     106 if (defined($p) && $anum >= $self->{min_format}*$self->{min_fraction}) {
56 10         28 $res_n = $mts * 10**($exp-$p);
57 10         18 $res_w = $self->{names}{$p};
58             } else {
59 8         11 $res_n = $anum;
60 8         14 $res_w = "";
61             }
62             # N::F has a limit of 15 num_decimals
63 18 100       69 my $e = ceil(log10($res_n)); $e = 0 if $e < 0;
  18         45  
64 18 50       27 my $def_nd = 15 - $e; $def_nd = 0 if $def_nd < 0;
  18         37  
65 18 50 100     87 my $nd = $self->{num_decimal} // 15; $nd = 0 if $nd < 0;
  18         44  
66 18 100       38 $nd = $def_nd if $nd > $def_nd;
67             #print "res_n=$res_n, nd=$nd\n";
68              
69 18 50       78 $res_n = $e > 15 ? $res_n : $self->{_nf}->format_number($res_n, $nd);
70              
71 18 100       1936 ($num < 0 ? "-" : "") . $res_n . ($res_w ? " $res_w" : "");
    100          
72             }
73              
74             1;
75             # ABSTRACT: Base class for Lingua::XX::Number::Format::MixWithWords
76              
77             __END__