File Coverage

blib/lib/Lingua/Base/Number/Format/MixWithWords.pm
Criterion Covered Total %
statement 59 59 100.0
branch 21 26 80.7
condition 10 12 83.3
subroutine 8 8 100.0
pod 0 1 0.0
total 98 106 92.4


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