|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package Math::Fraction;  | 
| 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Purpose: To Manipulate Exact Fractions  | 
| 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Copyright 1997 by Kevin Atkinson (kevina@cark.net)  | 
| 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Version .53b  (2 Feb 1998)  | 
| 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Beta Release  | 
| 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Originally Developed with Perl v 5.003_37 for Win32.  | 
| 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Has been testing on Perl Ver 5.003 on a solaris machine and Perl 5.004  | 
| 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # on Windows 95  | 
| 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Built on a Linux 2 machine with perl v5.003  | 
| 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Please send me feedback at kevina@clark.net  | 
| 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
15
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
5
 | 
 use vars qw($VERSION @ISA @EXPORT);  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
120
 | 
    | 
| 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 require Exporter;  | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 $VERSION = "0.53";  | 
| 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 @ISA = qw(Exporter);  | 
| 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 @EXPORT = qw(frac);  | 
| 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 @EXPORT_OK = qw(reduce string decimal num list is_tag);  | 
| 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 %EXPORT_TAGS = (  | 
| 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   STR_NUM => [qw(string decimal num)],  | 
| 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 );  | 
| 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
26
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
4
 | 
 use Carp;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
67
 | 
    | 
| 
27
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
5
 | 
 use strict;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
36
 | 
    | 
| 
28
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
3544
 | 
 use Math::BigInt;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
26155
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
    | 
| 
29
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
20108
 | 
 use Math::BigFloat;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21751
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
    | 
| 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 use overload  | 
| 
31
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
    "+"   => "add",  | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    "-"   => "sub",  | 
| 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    "*"   => "mul",  | 
| 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    "/"   => "div",  | 
| 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    "abs" => "abs",  | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    "**"  => "pow",  | 
| 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    "sqrt"=> "sqrt",  | 
| 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    "<=>" => "cmp",  | 
| 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    '""'  => "string",  | 
| 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    "0+"  => "decimal",  | 
| 
41
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
835
 | 
    "fallback" => 1;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
    | 
| 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my %DEF = (  | 
| 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   CURRENT => {TAGS => ['NORMAL','REDUCE','SMALL','AUTO'], DIGITS => undef, SYSTEM => 1, NAME => 'DEFAULT'},  | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   DEFAULT => {TAGS => ['NORMAL','REDUCE','SMALL','AUTO'], DIGITS => undef, READONLY=>1, SYSTEM=>1},  | 
| 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   BLANK   => {TAGS => ['','','']                 , DIGITS => ''   , READONLY=>1, SYSTEM=>1},  | 
| 
47
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 );  | 
| 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my ($OUTFORMAT, $REDUCE, $SIZE, $AUTO, $INTERNAL, $RED_STATE) = (0..5);  | 
| 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my $TAG_END = 3;          #Last index of tags ment to be kept.  | 
| 
51
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
52
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my %TAGS = (  | 
| 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   NORMAL     => [$OUTFORMAT, 'NORMAL'],  | 
| 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   MIXED      => [$OUTFORMAT, 'MIXED'],  | 
| 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   MIXED_RAW  => [$OUTFORMAT, 'MIXED_RAW'],  | 
| 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   RAW        => [$OUTFORMAT, 'RAW'],  | 
| 
57
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   DEF_MIXED  => [$OUTFORMAT, undef],  | 
| 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   REDUCE     => [$REDUCE, 'REDUCE'],  | 
| 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   NO_REDUCE  => [$REDUCE, 'NO_REDUCE'],  | 
| 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   DEF_REDUCE => [$REDUCE, undef],  | 
| 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   SMALL      => [$SIZE, 'SMALL'],  | 
| 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   BIG        => [$SIZE, 'BIG'],  | 
| 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   DEF_BIG    => [$SIZE, undef],  | 
| 
64
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   AUTO       => [$AUTO, 'AUTO'],  | 
| 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   NO_AUTO    => [$AUTO, 'NO_AUTO'],  | 
| 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   DEF_AUTO   => [$AUTO, undef],  | 
| 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   CONVERTED  => [$INTERNAL, 'CONVERTED'],  | 
| 
68
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   IS_REDUCED => [$RED_STATE, 'IS_REDUCED'],  | 
| 
69
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 );  | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my @DEF_TAG = qw(DEF_MIXED DEF_REDUCE DEF_BIG DEF_AUTO);  | 
| 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my $ID = 01;  | 
| 
74
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub new {  | 
| 
76
 | 
60
 | 
 
 | 
 
 | 
  
60
  
 | 
  
0
  
 | 
102
 | 
   my $proto = shift;  | 
| 
77
 | 
60
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
213
 | 
   my $class = ref($proto) || $proto;  | 
| 
78
 | 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
61
 | 
   my ($self, @frac, @tags, $tag, $decimal, $p1, $p2, $p3);  | 
| 
79
 | 
60
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
163
 | 
   if (&_is_decimal($_[0]) and &_is_decimal($_[1]) and &_is_decimal($_[2]) ) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
80
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
       my $sign = $_[0]/abs($_[0]);  | 
| 
81
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
       @tags = &_tags(@_[3..$#_]);  | 
| 
82
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
       ($decimal, $p1, $p2, $p3) = &_fix_num(\@tags, @_[0..2]);  | 
| 
83
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
       ($p1, $p2, $p3) = (abs($p1),abs($p2),abs($p3) );  | 
| 
84
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
       @frac = ($p1*$p3+$p2, $sign*$p3);  | 
| 
85
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
5
 | 
       @frac = &_de_decimal(@frac, \@tags) if $decimal;  | 
| 
86
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } elsif (&_is_decimal($_[0]) and &_is_decimal($_[1]) ) {  | 
| 
87
 | 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
139
 | 
       @tags = &_tags(@_[2..$#_]);  | 
| 
88
 | 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
124
 | 
       ($decimal, @frac) = &_fix_num(\@tags, @_[0..1]);  | 
| 
89
 | 
46
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
101
 | 
       @frac = &_de_decimal(@frac, \@tags) if $decimal;  | 
| 
90
 | 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
85
 | 
       @frac = &_simplify_sign(@frac);  | 
| 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } elsif (&_is_decimal($_[0]) ) {  | 
| 
92
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     {  | 
| 
93
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
       @tags = &_tags(@_[1..$#_]);  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
    | 
| 
94
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
       ($decimal, $p1) = &_fix_num(\@tags, $_[0]);  | 
| 
95
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
27
 | 
       @frac=($p1,1), last if not $decimal;  | 
| 
96
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
       (@frac[0..1], $tag) = &_from_decimal($p1);  | 
| 
97
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
       @tags = &_tags(@tags, $tag);  | 
| 
98
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
       ($decimal,@frac) = &_fix_num(\@tags, @frac);  | 
| 
99
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
10
 | 
       @frac = &_de_decimal(@frac, \@tags) if $decimal;  | 
| 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
101
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } elsif ($_[0] =~ /\s*([\+\-]?)\s*([0-9e\.\+\-]+)\s+([0-9e\.\+\-]+)\s*\/\s*([0-9e\.\+\-]+)/) {  | 
| 
102
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
       my $sign = $1.'1';  | 
| 
103
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
       @tags = &_tags(@_[1..$#_]);  | 
| 
104
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
       ($decimal, $p1, $p2, $p3) = &_fix_num(\@tags, $2, $3, $4);  | 
| 
105
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
       ($p1, $p2, $p3) = (abs($p1),abs($p2),abs($p3) );  | 
| 
106
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
       @frac = ($p1*$p3+$p2, $sign*$p3);  | 
| 
107
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
7
 | 
       @frac = &_de_decimal($p1*$p3+$p2, $sign*$p3, \@tags) if $decimal;  | 
| 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } elsif ($_[0] =~ /\s*([0-9e\.\+\-]+)\s*\/\s*([0-9e\.\+\-]+)/) {  | 
| 
109
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
       @tags = &_tags(@_[1..$#_]);  | 
| 
110
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
       ($decimal, @frac) = &_fix_num(\@tags, $1, $2);  | 
| 
111
 | 
5
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
15
 | 
       @frac = &_de_decimal(@frac, \@tags) if $decimal;  | 
| 
112
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
       @frac = &_simplify_sign(@frac);  | 
| 
113
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } else {  | 
| 
114
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       croak("\"$_[0]\" is of unknown format");  | 
| 
115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
116
 | 
60
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
204
 | 
   croak ("Can not have 0 as the denominator") if $frac[1] == 0;  | 
| 
117
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
118
 | 
60
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
1198
 | 
   if ( &_tag($REDUCE, \@tags) ne 'NO_REDUCE'  | 
| 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        and &_tag($RED_STATE, \@tags) ne 'IS_REDUCED' )  | 
| 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   {  | 
| 
121
 | 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
     my $not_reduced;  | 
| 
122
 | 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
187
 | 
     ($not_reduced, @frac) = &_reduce(@frac);  | 
| 
123
 | 
33
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
516
 | 
     @frac = &_fix_auto('DOWN',\@tags, @frac) if $not_reduced  | 
| 
124
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                        and &_tag($AUTO, \@tags) eq 'AUTO';  | 
| 
125
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
126
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                            | 
| 
127
 | 
60
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
150
 | 
   @tags[$RED_STATE] = undef if &_tag($RED_STATE, \@tags) eq 'IS_REDUCED';  | 
| 
128
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
129
 | 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
150
 | 
   $self->{'frac'}=\@frac;  | 
| 
130
 | 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
94
 | 
   $self->{'tags'}=\@tags;  | 
| 
131
 | 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
124
 | 
   bless ($self, $class);  | 
| 
132
 | 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
513
 | 
   return $self;  | 
| 
133
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
134
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
135
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # The following functions are met to be exported as shortcuts to method  | 
| 
136
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # operations.  | 
| 
137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
138
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub frac {  | 
| 
139
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #special exported function to simplify defining fractions  | 
| 
140
 | 
24
 | 
 
 | 
 
 | 
  
24
  
 | 
  
0
  
 | 
76
 | 
   return Math::Fraction->new(@_);  | 
| 
141
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
143
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Now are the methodes  | 
| 
144
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
145
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub string {  | 
| 
146
 | 
43
 | 
 
 | 
 
 | 
  
43
  
 | 
  
1
  
 | 
59
 | 
   my $self = shift;  | 
| 
147
 | 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
39
 | 
   my @frac;  | 
| 
148
 | 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
124
 | 
   my $mixed = &_tag ($OUTFORMAT, [$_[0]], $self->{'tags'} );  | 
| 
149
 | 
43
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
128
 | 
   if ($mixed eq 'MIXED') {  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
150
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
54
 | 
       @frac = $self->list('MIXED');  | 
| 
151
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
37
 | 
       my $string = "";  | 
| 
152
 | 
23
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
51
 | 
       $string .= "$frac[0]"           if $frac[0] != 0;  | 
| 
153
 | 
23
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
599
 | 
       $string .= " "                  if $frac[0] != 0 and $frac[1] !=0;  | 
| 
154
 | 
23
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
600
 | 
       $string .= "$frac[1]/$frac[2]"  if $frac[1] != 0;  | 
| 
155
 | 
23
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
805
 | 
       $string  = "0"                  if $string eq '';  | 
| 
156
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
527
 | 
       return $string;  | 
| 
157
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } elsif ($mixed eq 'MIXED_RAW') {  | 
| 
158
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       @frac = $self->list('MIXED');  | 
| 
159
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       return "$frac[0] $frac[1]/$frac[2]";  | 
| 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } elsif ($mixed eq 'RAW') {  | 
| 
161
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       @frac = $self->list;  | 
| 
162
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       return ($frac[0] >= 0 ? '+':'')."$frac[0]/$frac[1]";  | 
| 
163
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } else {  | 
| 
164
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
44
 | 
       @frac = $self->list;  | 
| 
165
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
152
 | 
       return "$frac[0]/$frac[1]";  | 
| 
166
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
167
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
168
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
169
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub list {  | 
| 
170
 | 
43
 | 
 
 | 
 
 | 
  
43
  
 | 
  
1
  
 | 
47
 | 
   my $self = shift;  | 
| 
171
 | 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
36
 | 
   my @frac = @{$self->{'frac'}};  | 
| 
 
 | 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
103
 | 
    | 
| 
172
 | 
43
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
96
 | 
   if ($_[0] eq "MIXED") {  | 
| 
173
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
41
 | 
     my $whole=$frac[0]/$frac[1];  | 
| 
174
 | 
23
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
407
 | 
     $whole=int($whole) if not ref($frac[0]);  | 
| 
175
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
37
 | 
     $frac[0] = abs($frac[0] - $frac[1]*$whole);  | 
| 
176
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
725
 | 
     @frac = ($whole, @frac);  | 
| 
177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
178
 | 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
67
 | 
   foreach (@frac) {s/^\+//;};  | 
| 
 
 | 
109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
401
 | 
    | 
| 
179
 | 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
229
 | 
   return @frac;  | 
| 
180
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
181
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
182
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub reduce {  | 
| 
183
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
   my $self = shift;  | 
| 
184
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my ($undef, @frac) = &_reduce(@{$self->{'frac'}});  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
185
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   return Math::Fraction->new(@frac, @{$self->{'tags'}});  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
186
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
187
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
188
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
189
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub decimal {  | 
| 
190
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
  
1
  
 | 
4
 | 
   my $self = shift;  | 
| 
191
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
   my @frac = @{$self->{'frac'}};  | 
| 
 
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
    | 
| 
192
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
11
 | 
   return $frac[0]/$frac[1] if not ref($frac[0]);  | 
| 
193
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   return Math::BigFloat->new(Math::BigFloat::fdiv($frac[0], $frac[1], $DEF{CURRENT}{DIGITS}) ) if ref($frac[0]);  | 
| 
194
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
195
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
196
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub num {  | 
| 
197
 | 
9
 | 
 
 | 
 
 | 
  
9
  
 | 
  
1
  
 | 
15
 | 
   my $self = shift;  | 
| 
198
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
   my @frac = @{$self->{'frac'}};  | 
| 
 
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
26
 | 
    | 
| 
199
 | 
9
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
45
 | 
   return $frac[0]/$frac[1] if not ref($frac[0]);  | 
| 
200
 | 
8
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
53
 | 
   return Math::BigFloat->new(Math::BigFloat::fdiv($frac[0], $frac[1], $DEF{CURRENT}{DIGITS}) ) if ref($frac[0]);  | 
| 
201
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
202
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
203
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ## For the next three methods:  | 
| 
204
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # If used on the object use the tags of the object  | 
| 
205
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # If given a class use the dafault tags,  | 
| 
206
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # .... if a default set is specified then return for that set.  | 
| 
207
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
208
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub is_tag {  | 
| 
209
 | 
6
 | 
 
 | 
 
 | 
  
6
  
 | 
  
1
  
 | 
10
 | 
   my $self = shift;  | 
| 
210
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
   my $tag = shift;  | 
| 
211
 | 
6
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
18
 | 
   my $default = 1 if $_[0] eq 'INC_DEF';  | 
| 
212
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
   my $is_tag = 0;  | 
| 
213
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
   my @tags;  | 
| 
214
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   {  | 
| 
215
 | 
6
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     $is_tag = 0, last if not $TAGS{$tag}; #if there is no such tag ret=0  | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
    | 
| 
216
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
     my ($num, $tag) = @{$TAGS{$tag}};  | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
    | 
| 
217
 | 
6
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
13
 | 
     if (ref($self) eq "Math::Fraction") {  | 
| 
218
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
       @tags = @{$self->{'tags'}};  | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
    | 
| 
219
 | 
6
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
21
 | 
       $is_tag = 1    , last if $tags[$num] eq $tag;  | 
| 
220
 | 
3
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
10
 | 
       $is_tag = undef, last if $tags[$num] eq undef and not $default;  | 
| 
221
 | 
3
 | 
  
  0
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
8
 | 
       $is_tag = -1   , last if $DEF{CURRENT}{TAGS}[$num] eq $tag  | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
222
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                              and $tags[$num] eq undef and $default;  | 
| 
223
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
       $is_tag = 0;   | 
| 
224
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
225
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       my $set;  | 
| 
226
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $set = 'CURRENT' unless $set = $_[0];  | 
| 
227
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $set = 'BLANK'   unless exists $DEF{$set};  | 
| 
228
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $is_tag = 1   , last if $DEF{$set}{TAGS}[$num] eq $tag;  | 
| 
229
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $is_tag = 0;  | 
| 
230
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
231
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
232
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
42
 | 
   return $is_tag;  | 
| 
233
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
234
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
235
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub tags {  | 
| 
236
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
  
1
  
 | 
6
 | 
   my $self = shift;  | 
| 
237
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
   my @tags;  | 
| 
238
 | 
5
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
14
 | 
   if (ref($self) eq "Math::Fraction") {  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
239
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $inc_def = 1 if $_[0] eq 'INC_DEF';  | 
| 
240
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     @tags = @{$self->{'tags'}}[0..$TAG_END];  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
241
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $num;  | 
| 
242
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     foreach $num (0 .. $#tags) {  | 
| 
243
 | 
0
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
       $tags[$num] = $DEF_TAG[$num]  if $tags[$num] eq undef and not $inc_def;  | 
| 
244
 | 
0
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
       $tags[$num] = $DEF{CURRENT}{TAGS}[$num] if $tags[$num] eq undef and $inc_def;  | 
| 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
246
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } elsif (ref($self) ne "Math::Fraction") {  | 
| 
247
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
     my $set;  | 
| 
248
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
12
 | 
     $set = 'CURRENT' unless $set = $_[0];  | 
| 
249
 | 
5
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
18
 | 
     $set = 'BLANK'   unless exists $DEF{$set};  | 
| 
250
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
     @tags = @{$DEF{$set}{TAGS}};  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
    | 
| 
251
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
252
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
   return @tags;  | 
| 
253
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
254
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
255
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub digits {  | 
| 
256
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
  
1
  
 | 
5
 | 
   my $self = shift;  | 
| 
257
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
   my $set;  | 
| 
258
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
9
 | 
   $set = 'CURRENT' unless $set = $_[0];  | 
| 
259
 | 
5
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
9
 | 
   $set = 'BLANK'   unless exists $DEF{$set};  | 
| 
260
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
   return $DEF{$set}{DIGITS};  | 
| 
261
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
262
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
263
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ##  | 
| 
264
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # These mehods are used form managing default sets.  | 
| 
265
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
266
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub sets {  | 
| 
267
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
   my $self = shift;  | 
| 
268
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   return keys %DEF;  | 
| 
269
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
270
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
271
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub name_set {  | 
| 
272
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
1
  
 | 
2
 | 
   shift;   | 
| 
273
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
4
 | 
   return $DEF{CURRENT}{NAME}  if not $_[0];  | 
| 
274
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
9
 | 
   $DEF{CURRENT}{NAME} = $_[0] if     $_[0];  | 
| 
275
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
276
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
277
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub exists_set {  | 
| 
278
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
1
  
 | 
10
 | 
   return exists $DEF{$_[1]};  | 
| 
279
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
280
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
281
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub use_set {  | 
| 
282
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
1
  
 | 
2
 | 
   my $self = shift;  | 
| 
283
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
   my $name = shift;  | 
| 
284
 | 
1
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
8
 | 
   if (exists $DEF{$name} and not $DEF{$name}{READONLY}) {  | 
| 
285
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
     $DEF{CURRENT} = $DEF{$name};  | 
| 
286
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
     return $name;  | 
| 
287
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } else {  | 
| 
288
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return undef;  | 
| 
289
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
290
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
291
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
292
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub temp_set {  | 
| 
293
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
  
1
  
 | 
3
 | 
   my $self = shift;  | 
| 
294
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
   my $name = shift;  | 
| 
295
 | 
2
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
4
 | 
   if (not $name) {  | 
| 
296
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
     $ID++;  | 
| 
297
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
     $name = "\cI\cD$ID";  | 
| 
298
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
     $self->copy_set('CURRENT', $name);  | 
| 
299
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
     $self->copy_set('DEFAULT', 'CURRENT');  | 
| 
300
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
     return $name;  | 
| 
301
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } else { #if $name;  | 
| 
302
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
     my $return = $self->copy_set($name, 'CURRENT');  | 
| 
303
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
     $self->del_set($name);  | 
| 
304
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     return $return  | 
| 
305
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
306
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
307
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
308
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
309
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub load_set {  | 
| 
310
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
  
1
  
 | 
4
 | 
   my $self = shift;  | 
| 
311
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
8
 | 
   if (exists $DEF{$_[0]}) {  | 
| 
312
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
14
 | 
     $self->copy_set($_[0],'CURRENT') if exists $DEF{$_[0]};  | 
| 
313
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
     return $_[0]  | 
| 
314
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } else {  | 
| 
315
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return undef;  | 
| 
316
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
317
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
318
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
319
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub save_set {  | 
| 
320
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
1
  
 | 
2
 | 
   my $self = shift;  | 
| 
321
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
   my $name;  | 
| 
322
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
4
 | 
   $name = $DEF{CURRENT}{NAME} unless $name = shift;  | 
| 
323
 | 
1
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
13
 | 
   ++$ID, $name = "\cI\cD:$ID" if not $name or $name eq 'RAND';  | 
| 
324
 | 
1
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
3
 | 
   return $self->copy_set('CURRENT', $name) && $name;  | 
| 
325
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
326
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
327
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub copy_set {  | 
| 
328
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
  
1
  
 | 
8
 | 
   shift;  | 
| 
329
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
   my ($name1, $name2) = @_;  | 
| 
330
 | 
7
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
51
 | 
   if ($DEF{$name2}{READONLY} or $name2 eq 'BLANK' or not exists $DEF{$name1}) {  | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
331
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return 0;  | 
| 
332
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } else {  | 
| 
333
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
     $DEF{$name2} = {};                         # kill any links from use;  | 
| 
334
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
     $DEF{$name2}{TAGS} = [@{$DEF{$name1}{TAGS}}];  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
    | 
| 
335
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
     $DEF{$name2}{DIGITS} = $DEF{$name1}{DIGITS};  | 
| 
336
 | 
7
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
15
 | 
     $DEF{$name2}{NAME} = $name2 unless $name2 eq 'CURRENT';  | 
| 
337
 | 
7
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
17
 | 
     $DEF{$name2}{NAME} = $name1   if   $name2 eq 'CURRENT';  | 
| 
338
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
     return 1;  | 
| 
339
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
340
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
341
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
342
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub del_set {  | 
| 
343
 | 
1
 | 
  
 50
  
 | 
  
 33
  
 | 
  
1
  
 | 
  
1
  
 | 
10
 | 
   if (exists $DEF{$_[1]} and not $DEF{$_[1]}{SYSTEM}) {  | 
| 
344
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
     delete $DEF{$_[1]};  | 
| 
345
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
     return $_[1];  | 
| 
346
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
347
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
348
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
349
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # All of the modify methods are not meant to return anything, they modify  | 
| 
350
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # the object being referenced too.  | 
| 
351
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
352
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub modify {  | 
| 
353
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # This method works almost like the new method except that it takes an  | 
| 
354
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # object as an argement and will modify it instead of creating a new  | 
| 
355
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # object, also any tags assosated with the object are left in tact  | 
| 
356
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # unless a new tag is given to override the old.  | 
| 
357
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
358
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
   my $me = shift;  | 
| 
359
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my $self;  | 
| 
360
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my @tags = @{$me->{'tags'}};  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
361
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   $self = Math::Fraction->new(@_, @tags, @_);  # The extra @_ is their to override tags  | 
| 
362
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   $me->{'frac'} = $self->{'frac'};  | 
| 
363
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   $me->{'tags'} = $self->{'tags'};  | 
| 
364
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
365
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
366
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub modify_digits {  | 
| 
367
 | 
6
 | 
 
 | 
 
 | 
  
6
  
 | 
  
0
  
 | 
10
 | 
   my $self = shift;  | 
| 
368
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
   $DEF{CURRENT}{DIGITS} = shift;  | 
| 
369
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
370
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
371
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub modify_reduce {  | 
| 
372
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
   my $me = shift;  | 
| 
373
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my $self = $me->reduce;  | 
| 
374
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   $me->{'frac'} = $self->{'frac'};  | 
| 
375
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   $me->{'tags'} = $self->{'tags'};  | 
| 
376
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
377
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
378
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
379
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub modify_num {  | 
| 
380
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
   my $self = shift;  | 
| 
381
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   $self->[0] = $_[0]  | 
| 
382
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
383
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
384
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub modify_den {  | 
| 
385
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
   my $self = shift;  | 
| 
386
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   $self->[1] = $_[0]  | 
| 
387
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
388
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
389
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub modify_tag {  | 
| 
390
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
  
1
  
 | 
12
 | 
   my $self = shift;  | 
| 
391
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
   my ($return, @return);  | 
| 
392
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my $newtag;  | 
| 
393
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
  foreach $newtag (@_) {  | 
| 
394
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
   my $tagnum = &_tagnum($newtag);  | 
| 
395
 | 
9
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
44
 | 
   if ($tagnum == -1) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
396
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     push @return, undef;  | 
| 
397
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } elsif (ref($self) eq "Math::Fraction") {  | 
| 
398
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
     my @frac = @{$self->{'frac'}};  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
    | 
| 
399
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
     my @tags = @{$self->{'tags'}};  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
    | 
| 
400
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
     my @newtags = &_tags(@tags,$newtag);  | 
| 
401
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Now transform the Fraction based on the new tag.  | 
| 
402
 | 
3
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
14
 | 
     if ($tagnum == $SIZE) {  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
403
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
37
 | 
       my $newtag = &_tag($SIZE, \@newtags);  | 
| 
404
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
5
 | 
       @frac = map { "$_"+0 } @frac                if $newtag eq 'SMALL';  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
405
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
5
 | 
       @frac = map { Math::BigInt->new($_) } @frac if $newtag eq 'BIG';  | 
| 
 
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
48
 | 
    | 
| 
406
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($tagnum == $REDUCE) {  | 
| 
407
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       (undef, @frac) = &_reduce(@frac) if &_tag($REDUCE, \@newtags) eq 'REDUCE';  | 
| 
408
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
409
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Finally Modify the Fraction  | 
| 
410
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38
 | 
     $self->{'frac'} = \@frac;   | 
| 
411
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
     $self->{'tags'} = \@newtags;  | 
| 
412
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } else {    | 
| 
413
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
     $DEF{CURRENT}{TAGS}[$tagnum] = $newtag;  | 
| 
414
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
415
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
   push @return, $newtag;  | 
| 
416
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  }  | 
| 
417
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
86
 | 
  return @return;  | 
| 
418
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
419
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
420
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # These methods are meant to be called with the overload operators.  | 
| 
421
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
422
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub add {  | 
| 
423
 | 
16
 | 
 
 | 
 
 | 
  
16
  
 | 
  
0
  
 | 
19
 | 
   my @frac1 = @{$_[0]->{'frac'}};  | 
| 
 
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
    | 
| 
424
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
   my @tags1 = @{$_[0]->{'tags'}};  | 
| 
 
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
62
 | 
    | 
| 
425
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
   my (@frac2, @frac, @tags2, $frac);  | 
| 
426
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
   my $skipauto = 0;  | 
| 
427
 | 
16
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
40
 | 
   @frac2 = @{$_[1]->{'frac'}}, @tags2 = @{$_[1]->{'tags'}} if ref($_[1]) eq "Math::Fraction";  | 
| 
 
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
37
 | 
    | 
| 
 
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
61
 | 
    | 
| 
428
 | 
16
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
73
 | 
   @frac2 = &_from_decimal($_[1]), $tags2[$INTERNAL] = 'CONVERTED' if ref($_[1]) ne "Math::Fraction";  | 
| 
429
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
68
 | 
   my @tags = &_tags_preserve([@tags1],[@tags2]);  | 
| 
430
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
431
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  LOOP: {  | 
| 
432
 | 
16
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
35
 | 
   if (&_tag($REDUCE, \@tags) eq 'NO_REDUCE') {  | 
| 
 
 | 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
35
 | 
    | 
| 
433
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
     @frac = ($frac1[0]*$frac2[1]+$frac2[0]*$frac1[1],$frac1[1]*$frac2[1]);  | 
| 
434
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } else {  | 
| 
435
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Taken from Knuth v2 (rev 2), p313.  | 
| 
436
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # It will always return a reduced fraction.  | 
| 
437
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
     my $gcd1 = &_gcd($frac1[1],$frac2[1]);  | 
| 
438
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
225
 | 
     my $tmp = $frac1[0]*($frac2[1]/$gcd1) + $frac2[0]*($frac1[1]/$gcd1);  | 
| 
439
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1720
 | 
     my $gcd2 = &_gcd($tmp,$gcd1);  | 
| 
440
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
43
 | 
     @frac = ( $tmp/$gcd2, ($frac1[1]/$gcd1)*($frac2[1]/$gcd2) );  | 
| 
441
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
896
 | 
     $tags[$RED_STATE] = 'IS_REDUCED';  | 
| 
442
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
443
 | 
17
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
37
 | 
   if ( (&_tag($AUTO, \@tags) eq 'AUTO') and (not $skipauto) and  | 
| 
 
 | 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
444
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
      ($tags[$SIZE] eq 'SMALL') and ($frac[0]=~/[eE]/ or $frac[1]=~/[eE]/) )  | 
| 
445
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   {  | 
| 
446
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
     (@frac1[0..1], @frac2[0..1]) = map { Math::BigInt->new($_) } (@frac1, @frac2);  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
183
 | 
    | 
| 
447
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
105
 | 
     $tags[$SIZE] = 'BIG';  | 
| 
448
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
     $skipauto = 1;  | 
| 
449
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
     redo LOOP;  | 
| 
450
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
451
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  }  | 
| 
452
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
52
 | 
   return Math::Fraction->new(@frac, @tags);  | 
| 
453
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
454
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
455
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub sub {  | 
| 
456
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
   my ($frac1, $frac2) = ($_[$_[2]], $_[not $_[2]]);  # swap if needed  | 
| 
457
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   $frac1 = Math::Fraction->new($frac1, 'CONVERTED')  if ref($frac1) ne "Math::Fraction";  | 
| 
458
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   $frac2 = Math::Fraction->new($frac2, 'CONVERTED')  if ref($frac2) ne "Math::Fraction";  | 
| 
459
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
460
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   $frac2 = Math::Fraction->new($frac2->{'frac'}[0], -$frac2->{'frac'}[1], @{$frac2->{'tags'}});  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
461
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
462
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   return $frac1 + $frac2;  | 
| 
463
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
464
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
465
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub mul {  | 
| 
466
 | 
6
 | 
 
 | 
 
 | 
  
6
  
 | 
  
0
  
 | 
8
 | 
   my @frac1 = @{$_[0]{'frac'}};  | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
    | 
| 
467
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
   my @tags1 = @{$_[0]{'tags'}};  | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
    | 
| 
468
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
   my (@frac2, @frac, @tags2);  | 
| 
469
 | 
6
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
16
 | 
   @frac2 = @{$_[1]->{'frac'}}, @tags2 = @{$_[1]->{'tags'}} if ref($_[1]) eq "Math::Fraction";  | 
| 
 
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
    | 
| 
 
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
    | 
| 
470
 | 
6
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
25
 | 
   @frac2 = (&_from_decimal($_[1])), $tags2[$INTERNAL] = 'CONVERTED' if ref($_[1]) ne "Math::Fraction";  | 
| 
471
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
   my @tags = &_tags_preserve([@tags1],[@tags2]);  | 
| 
472
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
   my $skipauto = 0;  | 
| 
473
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  LOOP: {  | 
| 
474
 | 
6
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
7
 | 
   if (&_tag($REDUCE, \@tags) eq 'NO_REDUCE') {  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
    | 
| 
475
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     @frac = ($frac1[0]*$frac2[0],$frac1[1]*$frac2[1]);  | 
| 
476
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } else {  | 
| 
477
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
     my($gcd1, $gcd2)=(&_gcd($frac1[0],$frac2[1]),&_gcd($frac2[0],$frac1[1]));  | 
| 
478
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
     $frac[0] = ($frac1[0]/$gcd1)*($frac2[0]/$gcd2);  | 
| 
479
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
635
 | 
     $frac[1] = ($frac1[1]/$gcd2)*($frac2[1]/$gcd1);  | 
| 
480
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
554
 | 
     $tags[$RED_STATE] =  'IS_REDUCED';  | 
| 
481
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
482
 | 
7
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
17
 | 
   if ( (&_tag($AUTO, \@tags) eq 'AUTO') and (not $skipauto) and  | 
| 
 
 | 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
483
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        ($tags[$SIZE] eq 'SMALL') and ($frac[0]=~/[eE]/ or $frac[1]=~/[eE]/) )  | 
| 
484
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   {  | 
| 
485
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
     (@frac1[0..1], @frac2[0..1]) = map { Math::BigInt->new($_) } (@frac1, @frac2);  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
82
 | 
    | 
| 
486
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25
 | 
     $tags[$SIZE] = 'BIG';  | 
| 
487
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
     $skipauto = 1;  | 
| 
488
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
     redo LOOP;  | 
| 
489
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
490
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  }  | 
| 
491
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25
 | 
   return Math::Fraction->new(@frac, @tags);  | 
| 
492
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
493
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
494
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub div {  | 
| 
495
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
   my ($frac1, $frac2) = ($_[$_[2]], $_[not $_[2]]);  # swap if needed  | 
| 
496
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   $frac1 = Math::Fraction->new($frac1, 'CONVERTED')  if ref($frac1) ne "Math::Fraction";  | 
| 
497
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   $frac2 = Math::Fraction->new($frac2, 'CONVERTED')  if ref($frac2) ne "Math::Fraction";  | 
| 
498
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
499
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   $frac2 = Math::Fraction->new($frac2->{'frac'}[1], $frac2->{'frac'}[0], @{$frac2->{'tags'}});  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
500
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       #Makes a copy of the fraction with the num and den switched.  | 
| 
501
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
502
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   return $frac1 * $frac2;  | 
| 
503
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
504
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
505
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub pow {  | 
| 
506
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
0
  
 | 
1
 | 
   my (@frac, @frac1, @tags1);  | 
| 
507
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
5
 | 
   @frac1 = @{$_[$_[2]]->{'frac'}}, @tags1 = @{$_[$_[2]]->{'tags'}} if ref($_[$_[2]]) eq "Math::Fraction";  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
    | 
| 
508
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
4
 | 
   @frac1 = &_from_decimal($_[$_[2]])                       if ref($_[$_[2]]) ne "Math::Fraction";  | 
| 
509
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1
 | 
   my $frac2;  | 
| 
510
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
5
 | 
   $frac2 = $_[not $_[2]]->decimal        if ref($_[not $_[2]]) eq "Math::Fraction";  | 
| 
511
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
5
 | 
   $frac2 = $_[not $_[2]]                 if ref($_[not $_[2]]) ne "Math::Fraction";  | 
| 
512
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
   my @tags = @tags1;  | 
| 
513
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
   my $skipauto = 0;  | 
| 
514
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
515
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25
 | 
  LOOP: {   | 
| 
516
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
   @frac = ($frac1[0]**$frac2,$frac1[1]**$frac2);  | 
| 
517
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
518
 | 
1
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
6
 | 
   if ( (&_tag($AUTO, \@tags) eq 'AUTO') and (not $skipauto) and  | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
519
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
      ($tags[$SIZE] eq 'SMALL') and ($frac[0]=~/[eE]/ or $frac[1]=~/[eE]/) )  | 
| 
520
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   {  | 
| 
521
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     @frac1 = map { Math::BigInt->new($_) } @frac1;  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
522
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $tags[$SIZE] = 'BIG';  | 
| 
523
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $skipauto = 1;  | 
| 
524
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     redo LOOP;  | 
| 
525
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
526
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  }  | 
| 
527
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
528
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
   return Math::Fraction->new(@frac, @tags);  | 
| 
529
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
530
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
531
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub sqrt {  | 
| 
532
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
   my $self = shift;  | 
| 
533
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my @frac = @{$self->{'frac'}};  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
534
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my @tags = @{$self->{'tags'}};  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
535
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my $ans;  | 
| 
536
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   if ( ref($frac[0]) ) {  | 
| 
537
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $frac[0] = Math::BigFloat->new( Math::BigFloat::fsqrt($frac[0], $DEF{CURRENT}{DIGITS}) );  | 
| 
538
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $frac[1] = Math::BigFloat->new( Math::BigFloat::fsqrt($frac[1], $DEF{CURRENT}{DIGITS}) );  | 
| 
539
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } else {  | 
| 
540
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     @frac = (sqrt($frac[0]) , sqrt($frac[1]));  | 
| 
541
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
542
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   return Math::Fraction->new(@frac, @tags);  | 
| 
543
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
544
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
545
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
546
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub abs {  | 
| 
547
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
   my $self = shift;  | 
| 
548
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my @frac = @{$self->{'frac'}};  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
549
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my @tags = @{$self->{'tags'}};  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
550
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   return Math::Fraction->new(abs($frac[0]),abs($frac[1]),@tags,'IS_REDUCED');  | 
| 
551
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
552
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
553
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub cmp {  | 
| 
554
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
   my @frac1 = @{$_[0]->{'frac'}};  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
555
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my @tags1 = @{$_[0]->{'tags'}};  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
556
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my (@frac2, @frac, @tags2, $x, $y);  | 
| 
557
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   @frac2 = @{$_[1]->{'frac'}}, @tags2 = @{$_[1]->{'tags'}} if ref($_[1]) eq "Math::Fraction";  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
558
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   @frac2 = &_from_decimal($_[1]), @tags2 = qw(CONVERTED)   if ref($_[1]) ne "Math::Fraction";  | 
| 
559
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my @tags = &_tags_preserve([@tags1],[@tags2]);  | 
| 
560
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   if (&_tag($REDUCE, \@tags) == 'NO_REDUCE') {  | 
| 
561
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $x = $frac1[0]*$frac2[1];  | 
| 
562
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $y = $frac2[0]*$frac1[1];  | 
| 
563
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } else {  | 
| 
564
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $gcd1 = &_gcd($frac1[1],$frac2[1]);  | 
| 
565
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $x = $frac1[0]*($frac2[1]/$gcd1);  | 
| 
566
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $y = $frac2[0]*($frac1[1]/$gcd1);  | 
| 
567
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
568
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   return $x <=> $y;  | 
| 
569
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
570
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
571
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # These function are that functions and not ment to be used as methods  | 
| 
572
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
573
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _fix_num {  | 
| 
574
 | 
63
 | 
 
 | 
 
 | 
  
63
  
 | 
 
 | 
74
 | 
   my $tagsref = shift;  | 
| 
575
 | 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
122
 | 
   my @return = @_;  | 
| 
576
 | 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
112
 | 
   my $auto = &_tag($AUTO, $tagsref) eq 'AUTO';  | 
| 
577
 | 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
118
 | 
   $tagsref->[$SIZE] = &_tag($SIZE, $tagsref);   | 
| 
578
 | 
63
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
136
 | 
   $tagsref->[$SIZE] = 'SMALL'  if $auto;  | 
| 
579
 | 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
119
 | 
   my $num;  | 
| 
580
 | 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
113
 | 
   my $decimal = 0;  | 
| 
581
 | 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
83
 | 
   foreach $num (@return) {  | 
| 
582
 | 
125
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
542
 | 
     if (ref($num) eq "Math::BigFloat") {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
583
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $tagsref->[$SIZE] = 'BIG' unless $auto;  | 
| 
584
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $decimal = 1;  | 
| 
585
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif (ref($num) eq "Math::BigInt") {  | 
| 
586
 | 
12
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
25
 | 
       $tagsref->[$SIZE] = 'BIG' unless $auto;  | 
| 
587
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif (ref($num)) {  | 
| 
588
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       # do nothing  | 
| 
589
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($num =~ /[\.\e\E]/) {  | 
| 
590
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
       $decimal = 1;  | 
| 
591
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
592
 | 
125
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
361
 | 
     if ($auto) {  | 
| 
593
 | 
123
 | 
 
 | 
 
 | 
 
 | 
 
 | 
444
 | 
       $num =~ /[\+\-]?\s*0*([0-9]*)\s*\.?\s*([0-9]*)0*/;  | 
| 
594
 | 
123
 | 
 
 | 
 
 | 
 
 | 
 
 | 
643
 | 
       my $length = length($1)+length($2);  | 
| 
595
 | 
123
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
408
 | 
       $tagsref->[$SIZE] = 'BIG' if $length > 15;  | 
| 
596
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
597
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
598
 | 
63
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
175
 | 
   if ($tagsref->[$SIZE] eq 'BIG') {  | 
| 
599
 | 
10
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
29
 | 
     @return = map {Math::BigInt->new("$_")}   @return  if not $decimal;  | 
| 
 
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
593
 | 
    | 
| 
600
 | 
10
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
408
 | 
     @return = map {Math::BigFloat->new("$_")} @return  if     $decimal;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
    | 
| 
601
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
602
 | 
63
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
708
 | 
   if ($tagsref->[$SIZE] eq 'SMALL' and $auto) {  | 
| 
603
 | 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
81
 | 
     @return = map {"$_"+0} @return;  | 
| 
 
 | 
106
 | 
 
 | 
 
 | 
 
 | 
 
 | 
402
 | 
    | 
| 
604
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
605
 | 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
351
 | 
   return ($decimal, @return);  | 
| 
606
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
607
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
608
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _fix_auto {  | 
| 
609
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
10
 | 
   my $direction = shift;  | 
| 
610
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
   my $tagsref = shift;  | 
| 
611
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
   my @return = @_;  | 
| 
612
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
   $tagsref->[$SIZE] = 'SMALL';  | 
| 
613
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
   my $num;  | 
| 
614
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
   foreach $num (@return) {  | 
| 
615
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
91
 | 
     $num =~ /[\+\-]?\s*0*([0-9]*)\s*\.?\s*([0-9]*)0*/;  | 
| 
616
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
133
 | 
     my $length = length($1)+length($2);  | 
| 
617
 | 
16
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
50
 | 
     $tagsref->[$SIZE] = 'BIG' if $length > 15;  | 
| 
618
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
619
 | 
8
 | 
  
 50
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
43
 | 
   if ($tagsref->[$SIZE] eq 'BIG' and $direction eq 'BOTH') {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
620
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     @return = map {Math::BigInt->new("$_")} @return;  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
621
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } elsif ($tagsref->[$SIZE] eq 'SMALL') {  | 
| 
622
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
     @return = map {"$_"+0} @return;  | 
| 
 
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
61
 | 
    | 
| 
623
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
624
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
   return (@return);  | 
| 
625
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
626
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
627
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _is_decimal {  | 
| 
628
 | 
282
 | 
 
 | 
 
 | 
  
282
  
 | 
 
 | 
901
 | 
   my $return = $_[0] =~ /^\s*[\+\-0-9eE\.]+\s*$/;  | 
| 
629
 | 
282
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1827
 | 
   return $return;  | 
| 
630
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
631
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
632
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _reduce {  | 
| 
633
 | 
33
 | 
 
 | 
 
 | 
  
33
  
 | 
 
 | 
73
 | 
   my @frac = @_;  | 
| 
634
 | 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
62
 | 
   my $gcd = &_gcd(@frac);  | 
| 
635
 | 
33
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
60
 | 
   if ($gcd == 1 ) {  | 
| 
636
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
178
 | 
     return (0, @frac)  | 
| 
637
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } else {  | 
| 
638
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
256
 | 
     return (1, $frac[0]/$gcd, $frac[1]/$gcd);  | 
| 
639
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
640
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }    | 
| 
641
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
642
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _simplify_sign {  | 
| 
643
 | 
51
 | 
 
 | 
 
 | 
  
51
  
 | 
 
 | 
80
 | 
   my @frac = @_;  | 
| 
644
 | 
51
 | 
 
 | 
 
 | 
 
 | 
 
 | 
52
 | 
   my $sign = 1;  | 
| 
645
 | 
51
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
149
 | 
   $sign = ($frac[0]/abs($frac[0]))*($frac[1]/abs($frac[1])) if $frac[0];  | 
| 
646
 | 
51
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2690
 | 
   @frac = ($sign*abs($frac[0]), abs($frac[1]) );  | 
| 
647
 | 
51
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1004
 | 
   return @frac;  | 
| 
648
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
649
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
650
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _tags {  | 
| 
651
 | 
66
 | 
 
 | 
 
 | 
  
66
  
 | 
 
 | 
114
 | 
   my @return = (undef, undef);  | 
| 
652
 | 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
84
 | 
   my ($NUM, $VALUE) = (0, 1);  | 
| 
653
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
654
 | 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
105
 | 
   foreach (@_) {  | 
| 
655
 | 
181
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
396
 | 
     next if not $TAGS{$_};  | 
| 
656
 | 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
69
 | 
     my ($num, $value) = @{$TAGS{$_}};  | 
| 
 
 | 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
177
 | 
    | 
| 
657
 | 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
382
 | 
     $return[$num] = $value;  | 
| 
658
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
659
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
660
 | 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
206
 | 
   return @return;  | 
| 
661
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
662
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
663
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
664
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _tag {  | 
| 
665
 | 
402
 | 
 
 | 
 
 | 
  
402
  
 | 
 
 | 
472
 | 
   my $item = shift;  | 
| 
666
 | 
402
 | 
 
 | 
 
 | 
 
 | 
 
 | 
459
 | 
   my $return;  | 
| 
667
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my $ref;  | 
| 
668
 | 
402
 | 
 
 | 
 
 | 
 
 | 
 
 | 
813
 | 
   foreach $ref (@_, $DEF{CURRENT}{TAGS}) {  | 
| 
669
 | 
752
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
683
 | 
     last if $return = ${$ref}[$item];  | 
| 
 
 | 
752
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1863
 | 
    | 
| 
670
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
671
 | 
402
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1498
 | 
   return $return  | 
| 
672
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
673
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
674
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _tagnum {  | 
| 
675
 | 
9
 | 
 
 | 
 
 | 
  
9
  
 | 
 
 | 
9
 | 
   my $item = shift;  | 
| 
676
 | 
9
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
23
 | 
   if (exists $TAGS{$item}) {  | 
| 
677
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
     return $TAGS{$item}[0];  | 
| 
678
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } else {  | 
| 
679
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return -1;  | 
| 
680
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
681
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
682
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
683
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _tags_preserve {  | 
| 
684
 | 
22
 | 
 
 | 
 
 | 
  
22
  
 | 
 
 | 
23
 | 
   my @tags1 = @{$_[0]};  | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
47
 | 
    | 
| 
685
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
   my @tags2 = @{$_[1]};  | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
56
 | 
    | 
| 
686
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
28
 | 
   my @tags;  | 
| 
687
 | 
22
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
65
 | 
   if ($tags1[$INTERNAL] eq 'CONVERTED') {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
688
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     @tags = @tags2;  | 
| 
689
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } elsif ($tags2[$INTERNAL] eq 'CONVERTED') {  | 
| 
690
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
     @tags = @tags1;  | 
| 
691
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } else {  | 
| 
692
 | 
13
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
24
 | 
     @tags = map {$tags1[$_] eq $tags2[$_] and $tags1[$_]} (0 .. $#tags1) ;  | 
| 
 
 | 
51
 | 
 
 | 
 
 | 
 
 | 
 
 | 
235
 | 
    | 
| 
693
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
694
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
76
 | 
   return @tags;  | 
| 
695
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
696
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
697
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _gcd {  | 
| 
698
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # Using Euclid's method found in Knuth v2 (rev 2) p320 brought to my  | 
| 
699
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # attention from the BigInt module  | 
| 
700
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
701
 | 
77
 | 
 
 | 
 
 | 
  
77
  
 | 
 
 | 
138
 | 
   my ($x, $y) = (abs($_[0]), abs($_[1]));  | 
| 
702
 | 
77
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
540
 | 
   if ( ref($x) ) {  | 
| 
703
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
36
 | 
     $x = Math::BigInt->new( $x->bgcd($y) );  | 
| 
704
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } else {  | 
| 
705
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     {  | 
| 
706
 | 
65
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
61
 | 
       $x=1, last if $y > 1e17; # If this is so % will thinks its a zero so if  | 
| 
 
 | 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
157
 | 
    | 
| 
707
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                # $y>1e17 will simply will basicly give up and  | 
| 
708
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                # have it return 1 as the GCD.  | 
| 
709
 | 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
63
 | 
       my ($x0);  | 
| 
710
 | 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
207
 | 
       while ($y != 0) {  | 
| 
711
 | 
240
 | 
 
 | 
 
 | 
 
 | 
 
 | 
212
 | 
         $x0 = $x;  | 
| 
712
 | 
240
 | 
 
 | 
 
 | 
 
 | 
 
 | 
348
 | 
         ($x, $y) = ($y, $x % $y);  | 
| 
713
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # Note $x0 = $x, $x = $y, $y= $x % $y   Before the Swith  | 
| 
714
 | 
240
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
1319
 | 
         $x=1, last  if ($x0>99999999 or $x>999999999) and int($x0/$x)*$x+$y != $x0;  | 
| 
 
 | 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
715
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # This is to see if the mod operater through up on us when dealing with  | 
| 
716
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # large numbers.  If it did set the gcd = 1 and quit.  | 
| 
717
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
718
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
719
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
720
 | 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10677
 | 
   return $x;  | 
| 
721
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
722
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
723
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _de_decimal {  | 
| 
724
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
3
 | 
     my @frac = @_;  | 
| 
725
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
     my @return;  | 
| 
726
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
     my $big = &_tag($SIZE, $_[2]);  | 
| 
727
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
     my (@int_part, @decimal_part);  | 
| 
728
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
4
 | 
     if ($big eq "BIG") {  | 
| 
729
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       my @digits = (1,1);  | 
| 
730
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       ($int_part[0], $digits[0]) = $frac[0]->fnorm =~ /(\d+)E\-(\d+)/;  | 
| 
731
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       ($int_part[1], $digits[1]) = $frac[1]->fnorm =~ /(\d+)E\-(\d+)/;  | 
| 
732
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       @digits = sort {$a <=> $b} @digits;  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
733
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       my $factor = 10**$digits[1];  | 
| 
734
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       @frac = (($_[0]*$factor),($_[1]*$factor));  | 
| 
735
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       chop $frac[0]; chop $frac[1];  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
736
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       @frac = (Math::BigInt->new($frac[0]), Math::BigInt->new($frac[1]) );  | 
| 
737
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    } else {  | 
| 
738
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
       ($int_part[0], $decimal_part[0]) = $frac[0] =~ /(\d+)\.(\d+)/;  | 
| 
739
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
       ($int_part[1], $decimal_part[1]) = $frac[1] =~ /(\d+)\.(\d+)/;  | 
| 
740
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
       @decimal_part = sort {$a <=> $b} (length($decimal_part[0]),length($decimal_part[1]) );  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
    | 
| 
741
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
       my $factor = 10**$decimal_part[1];  | 
| 
742
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
       @frac = ($_[0]*$factor, $_[1]*$factor);  | 
| 
743
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    }  | 
| 
744
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
    return @frac;  | 
| 
745
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
746
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
747
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _from_decimal {  | 
| 
748
 | 
12
 | 
 
 | 
 
 | 
  
12
  
 | 
 
 | 
23
 | 
   my $decimal = shift;       # the decimal (1.312671267127)  | 
| 
749
 | 
12
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
117
 | 
   my $big = 'BIG' if ref($decimal);  | 
| 
750
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
   my ($repeat);              # flag to keep track if it is repeating or not  | 
| 
751
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my ($sign);  | 
| 
752
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my ($factor, $int_factor);  | 
| 
753
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my ($factor2);  | 
| 
754
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my ($whole_num, $whole_num_len);  | 
| 
755
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my ($int_part);                        # integer part (1)  | 
| 
756
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my ($decimal_part, $decimal_part_len); # decimal part (312671267127)  | 
| 
757
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my ($decimal_part2);               # decimal part - last bit \/ (312671267)  | 
| 
758
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my ($pat, $pat_len);               # repeating pat (1267)  | 
| 
759
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my ($pat_lastb);                   # last bit of repeating pat (127)  | 
| 
760
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my ($beg_part, $beg_part_len);       # non-repeating part (3)  | 
| 
761
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my ($other_part, $other_part_len);   # repeating part     (1267126712127)  | 
| 
762
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my ($frac1, $frac2, $frac3);  | 
| 
763
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
764
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
68
 | 
   my $rnd_mode = $Math::BigFloat::rnd_mode;  # to avoid problems with incon.  | 
| 
765
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
81
 | 
   $Math::BigFloat::rnd_mode = 'trunc';       # rounding  | 
| 
766
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
767
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
238
 | 
   $decimal = "$decimal";  | 
| 
768
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
137
 | 
   $decimal =~ s/\s//g;  | 
| 
769
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
44
 | 
   ($sign, $int_part, $decimal_part) = $decimal =~ /([\+\-]?)\s*(\d*)\.(\d+)$/;  | 
| 
770
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
   $sign .= '1';  | 
| 
771
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
   $decimal_part_len = length($decimal_part);  | 
| 
772
 | 
12
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
30
 | 
   $int_part = "" unless $int_part;  | 
| 
773
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
   $factor = '1'.'0'x(length($decimal_part));  | 
| 
774
 | 
12
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
43
 | 
   $factor = Math::BigFloat->new($factor) if $big;  | 
| 
775
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
      # Make it a BigFloat now to simplfy latter  | 
| 
776
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
287
 | 
   $int_factor = '1'.'0'x(length($int_part));  | 
| 
777
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
   $beg_part_len = 0;  | 
| 
778
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  OuterBlock:  | 
| 
779
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
   while ($beg_part_len < $decimal_part_len) {  | 
| 
780
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
57
 | 
     $beg_part = substr($decimal_part, 0, $beg_part_len);  | 
| 
781
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
51
 | 
     $other_part = substr($decimal_part, $beg_part_len);  | 
| 
782
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
30
 | 
     $other_part_len = length($other_part);  | 
| 
783
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
     my $i;  | 
| 
784
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
79
 | 
     for ($i = 1; $i < ($other_part_len/2+1); $i++) {  | 
| 
785
 | 
582
 | 
 
 | 
 
 | 
 
 | 
 
 | 
672
 | 
       $pat = substr($other_part, 0, $i);  | 
| 
786
 | 
582
 | 
 
 | 
 
 | 
 
 | 
 
 | 
518
 | 
       $pat_len = $i;  | 
| 
787
 | 
582
 | 
 
 | 
 
 | 
 
 | 
 
 | 
566
 | 
       local $_ = $other_part;  | 
| 
788
 | 
582
 | 
 
 | 
 
 | 
 
 | 
 
 | 
496
 | 
       $repeat = undef;  | 
| 
789
 | 
582
 | 
 
 | 
 
 | 
 
 | 
 
 | 
479
 | 
       while (1) {  | 
| 
790
 | 
1243
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6917
 | 
         ($_) = /^$pat(.*)/;  | 
| 
791
 | 
1243
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1375
 | 
         my $length = length($_);  | 
| 
792
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
793
 | 
1243
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
2509
 | 
         if ( $length <= $pat_len) {  | 
| 
794
 | 
612
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
2004
 | 
           last unless $length;  | 
| 
795
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
41
 | 
           $pat_lastb = substr($pat, 0, $length);  | 
| 
796
 | 
34
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
62
 | 
           $repeat=1 ,last OuterBlock if $pat_lastb eq $_;  | 
| 
797
 | 
32
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
152
 | 
           if ($pat_lastb eq $_ - 1) {  | 
| 
798
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
              # this is needed to see if it really is the repeating fracton  | 
| 
799
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
              # we intented it to be.  If we don't do this 1.1212 would become  | 
| 
800
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
              # 1120/999 = 1.1211211211.  | 
| 
801
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
              # The first three lines converts it to a fraction and the  | 
| 
802
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
              # rests tests it to the actual repeating decimal/  | 
| 
803
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
              # The NO_REDUCE flag is their to save time as reducing large  | 
| 
804
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
              # fraction can take a bit of time which is unnecessary as we will  | 
| 
805
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
              # be converting it to a decimal.  | 
| 
806
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
             $decimal_part2 = substr($decimal_part, 0, $decimal_part_len - length($pat_lastb));  | 
| 
807
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
             $factor2 = '1'.'0'x(length($decimal_part2));  | 
| 
808
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25
 | 
             $frac1 = Math::Fraction->new('0'.$beg_part,"1"."0"x$beg_part_len, 'NO_REDUCE', $big);  | 
| 
809
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1112
 | 
             $frac2 = Math::Fraction->new('0'.$pat,"9"x$pat_len."0"x$beg_part_len, 'NO_REDUCE', $big);  | 
| 
810
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
             $frac3 = $frac1 + $frac2;  | 
| 
811
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
             my $what_i_get = $frac3->decimal;  | 
| 
812
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
             my $places = length($what_i_get);  | 
| 
813
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
7
 | 
             my $decimal_p_tmp = $decimal_part2                      if not $big;  | 
| 
814
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
5
 | 
                $decimal_p_tmp = Math::BigFloat->new($decimal_part2) if  $big;  | 
| 
815
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
             my $what_i_should_get = (($decimal_p_tmp)/$factor2)."$pat"x($places);  | 
| 
816
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
               # The rest of this is doing nothing more but trying to compare  | 
| 
817
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
               # the what_i_get and what_i_should_get but becuse the stupid  | 
| 
818
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
               # BigFloat module is so pragmentic all this hopla is nessary  | 
| 
819
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
6
 | 
             $what_i_should_get = Math::BigFloat->new($what_i_should_get)           if $big;  | 
| 
820
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
5
 | 
             $what_i_should_get = $what_i_should_get->fround(length($what_i_get)-1) if $big;  | 
| 
821
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
5
 | 
             $what_i_should_get = Math::BigFloat->new($what_i_should_get)           if $big;  | 
| 
822
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
               # ^^ Needed because the dam fround method does not return a  | 
| 
823
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
               #    BigFloat object!!!!!!  | 
| 
824
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
5
 | 
             my $pass = "$what_i_get" eq "$what_i_should_get" if $big;  | 
| 
825
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
10
 | 
                $pass = $what_i_get == $what_i_should_get  if  not $big;  | 
| 
826
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
16
 | 
             $repeat=1, last OuterBlock if ($pass);  | 
| 
827
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
           }  | 
| 
828
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
829
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
830
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
831
 | 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
52
 | 
     $beg_part_len++;  | 
| 
832
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
833
 | 
12
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
21
 | 
   if ($repeat) {  | 
| 
834
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
29
 | 
     $frac1 = Math::Fraction->new('0'.$beg_part,"1"."0"x$beg_part_len, $big);  | 
| 
835
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25
 | 
     $frac2 = Math::Fraction->new('0'.$pat,"9"x$pat_len."0"x$beg_part_len, $big);  | 
| 
836
 | 
4
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
17
 | 
     $int_part = Math::Fraction->new('0'.$int_part, 1, 'BIG') if $big;  | 
| 
837
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
     $frac3 = $sign*($int_part + $frac1 + $frac2);  | 
| 
838
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
     return @{$frac3->{'frac'}};  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
40
 | 
    | 
| 
839
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } else {  | 
| 
840
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
44
 | 
     return ($decimal*$factor, $factor, $big);  | 
| 
841
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
842
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $Math::BigFloat::rnd_mode = $rnd_mode;   # set it back to what it was.  | 
| 
843
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
844
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
845
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  | 
| 
846
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
847
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 __END__  |