File Coverage

blib/lib/Math/RNG/Microsoft/FCPro.pm
Criterion Covered Total %
statement 46 50 92.0
branch 8 12 66.6
condition n/a
subroutine 13 14 92.8
pod 4 4 100.0
total 71 80 88.7


line stmt bran cond sub pod time code
1             package Math::RNG::Microsoft::FCPro;
2             $Math::RNG::Microsoft::FCPro::VERSION = '0.2.0';
3 1     1   467 use 5.014;
  1         4  
4 1     1   5 use strict;
  1         2  
  1         20  
5 1     1   5 use warnings;
  1         2  
  1         22  
6 1     1   5 use integer;
  1         2  
  1         5  
7 1     1   547 use bigint;
  1         5626  
  1         5  
8              
9              
10             my $MAX_SEED = ( ( 1 << ( 31 + 2 ) ) - 1 ); # 33 bits
11              
12             sub new
13             {
14 2     2 1 2774 my $class = shift;
15              
16 2         6 my $self = bless {}, $class;
17              
18 2         8 $self->_init(@_);
19              
20 2         6 return $self;
21             }
22              
23             sub _seed
24             {
25 26     26   46 my $self = shift;
26              
27 26 100       61 if (@_)
28             {
29 2         8 $self->{_seed} = shift;
30             }
31              
32 26         70 return $self->{_seed};
33             }
34              
35             sub _seedx
36             {
37 38     38   5651 my $self = shift;
38              
39 38 100       82 if (@_)
40             {
41 14         28 $self->{_seedx} = shift;
42             }
43              
44 38         86 return $self->{_seedx};
45             }
46              
47             my $X = hex("0x100000000");
48              
49             sub _init
50             {
51 2     2   6 my ( $self, %args ) = @_;
52              
53 2         6 my $seed = $self->_seed( $args{seed} );
54 2 50       42 $self->_seedx( ( $seed < $X ) ? $seed : ( $seed - $X ) );
55 2         10 return;
56             }
57              
58             sub rand
59             {
60 12     12 1 26 my ( $self, ) = @_;
61              
62 12 50       24 if ( $self->_seed < $X )
63             {
64 12         826 my $ret = $self->_rando();
65 12 50       3897 return ( ( $self->_seed < 0x80000000 ) ? $ret : ( $ret | 0x8000 ) );
66             }
67             else
68             {
69 0         0 return $self->_randp() + 1;
70             }
71             }
72              
73             sub _rando
74             {
75 12     12   20 my $self = shift;
76 12         26 $self->_seedx( ( $self->_seedx() * 214013 + 2531011 ) & $MAX_SEED );
77 12         47 return ( ( $self->_seedx >> 16 ) & 0x7fff );
78             }
79              
80             sub _randp
81             {
82 0     0   0 my $self = shift;
83 0         0 $self->_seedx( ( $self->_seedx() * 214013 + 2531011 ) & $MAX_SEED );
84 0         0 return ( ( $self->_seedx >> 16 ) & 0xffff );
85             }
86              
87             sub max_rand
88             {
89 9     9 1 1406 my ( $self, $max ) = @_;
90              
91 9         19 return ( $self->rand() % $max );
92             }
93              
94             sub shuffle
95             {
96 1     1 1 8 my ( $self, $deck ) = @_;
97              
98 1 50       3 if (@$deck)
99             {
100 1         3 my $i = @$deck;
101 1         4 while ( --$i )
102             {
103 9         358 my $j = $self->max_rand( $i + 1 );
104 9         1575 @$deck[ $i, $j ] = @$deck[ $j, $i ];
105             }
106             }
107              
108 1         61 return $deck;
109             }
110              
111              
112             1;
113              
114             __END__