| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Math::Rand48::Cursor; |
|
2
|
|
|
|
|
|
|
|
|
3
|
7
|
|
|
7
|
|
893261
|
use v5.34; |
|
|
7
|
|
|
|
|
20
|
|
|
4
|
7
|
|
|
7
|
|
28
|
use warnings; |
|
|
7
|
|
|
|
|
11
|
|
|
|
7
|
|
|
|
|
357
|
|
|
5
|
7
|
|
|
7
|
|
2816
|
use experimental qw(signatures); |
|
|
7
|
|
|
|
|
19488
|
|
|
|
7
|
|
|
|
|
35
|
|
|
6
|
7
|
|
|
7
|
|
5621
|
use Carp qw(croak); |
|
|
7
|
|
|
|
|
15
|
|
|
|
7
|
|
|
|
|
325
|
|
|
7
|
7
|
|
|
7
|
|
6229
|
use Math::BigInt; |
|
|
7
|
|
|
|
|
144200
|
|
|
|
7
|
|
|
|
|
32
|
|
|
8
|
7
|
|
|
7
|
|
93669
|
use Math::BigFloat; |
|
|
7
|
|
|
|
|
214568
|
|
|
|
7
|
|
|
|
|
49
|
|
|
9
|
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
our $VERSION = '0.001'; |
|
11
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
my $M = Math::BigInt->bone->blsft(48); |
|
13
|
|
|
|
|
|
|
my $A = Math::BigInt->from_hex('5DEECE66D'); # drand48 multiplier |
|
14
|
|
|
|
|
|
|
my $C = Math::BigInt->new(11); # drand48 increment |
|
15
|
|
|
|
|
|
|
my $AI = $A->copy->bmodinv($M); |
|
16
|
|
|
|
|
|
|
my $CI = ( -$AI * $C ) % $M; |
|
17
|
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
# Compose the step x -> a*x + c with itself n times, by squaring. |
|
19
|
172
|
|
|
172
|
|
8682
|
sub _affine_pow ( $a, $c, $n ) { |
|
|
172
|
|
|
|
|
217
|
|
|
|
172
|
|
|
|
|
192
|
|
|
|
172
|
|
|
|
|
161
|
|
|
|
172
|
|
|
|
|
181
|
|
|
20
|
172
|
|
|
|
|
454
|
my ( $ra, $rc ) = ( Math::BigInt->bone, Math::BigInt->bzero ); |
|
21
|
172
|
|
|
|
|
11635
|
my ( $ba, $bc ) = ( $a->copy, $c->copy ); |
|
22
|
172
|
|
|
|
|
5036
|
until ( $n->is_zero ) { |
|
23
|
880
|
100
|
|
|
|
354498
|
( $ra, $rc ) = ( ( $ba * $ra ) % $M, ( $ba * $rc + $bc ) % $M ) |
|
24
|
|
|
|
|
|
|
if $n->is_odd; |
|
25
|
880
|
|
|
|
|
232599
|
( $ba, $bc ) = ( ( $ba * $ba ) % $M, ( $ba * $bc + $bc ) % $M ); |
|
26
|
880
|
|
|
|
|
602645
|
$n->brsft(1); |
|
27
|
|
|
|
|
|
|
} |
|
28
|
172
|
|
|
|
|
82249
|
return ( $ra, $rc ); |
|
29
|
|
|
|
|
|
|
} |
|
30
|
|
|
|
|
|
|
|
|
31
|
124
|
|
|
124
|
1
|
320192
|
sub new ( $class, %arg ) { |
|
|
124
|
|
|
|
|
179
|
|
|
|
124
|
|
|
|
|
227
|
|
|
|
124
|
|
|
|
|
151
|
|
|
32
|
|
|
|
|
|
|
my $state = |
|
33
|
|
|
|
|
|
|
defined $arg{state} |
|
34
|
124
|
50
|
|
|
|
576
|
? Math::BigInt->new("$arg{state}") |
|
35
|
|
|
|
|
|
|
: Math::BigInt->bzero; |
|
36
|
124
|
|
|
|
|
10468
|
return bless { state => $state % $M }, $class; |
|
37
|
|
|
|
|
|
|
} |
|
38
|
|
|
|
|
|
|
|
|
39
|
27
|
|
|
27
|
1
|
136989
|
sub from_rand ( $class, $obs ) { |
|
|
27
|
|
|
|
|
36
|
|
|
|
27
|
|
|
|
|
33
|
|
|
|
27
|
|
|
|
|
32
|
|
|
40
|
27
|
|
|
|
|
121
|
return $class->new( state => sprintf '%.0f', $obs * 2**48 ); |
|
41
|
|
|
|
|
|
|
} |
|
42
|
|
|
|
|
|
|
|
|
43
|
45
|
|
|
45
|
1
|
451973
|
sub from_seed48 ( $class, $seed ) { |
|
|
45
|
|
|
|
|
66
|
|
|
|
45
|
|
|
|
|
55
|
|
|
|
45
|
|
|
|
|
44
|
|
|
44
|
45
|
|
|
|
|
195
|
my $n = Math::BigFloat->new("$seed"); |
|
45
|
45
|
100
|
100
|
|
|
5015
|
croak "from_seed48() seed must be a finite number, got '$seed'" |
|
46
|
|
|
|
|
|
|
if $n->is_nan || $n->is_inf; |
|
47
|
41
|
|
|
|
|
606
|
my $int = $n->babs->bfloor->as_int; |
|
48
|
41
|
|
|
|
|
17178
|
my $x = $int->blsft(16)->bior( Math::BigInt->from_hex('330e') ); |
|
49
|
41
|
|
|
|
|
40135
|
return $class->new( state => $x ); |
|
50
|
|
|
|
|
|
|
} |
|
51
|
|
|
|
|
|
|
|
|
52
|
152
|
|
|
152
|
1
|
6066
|
sub state ($self) { $self->{state}->copy } |
|
|
152
|
|
|
|
|
188
|
|
|
|
152
|
|
|
|
|
174
|
|
|
|
152
|
|
|
|
|
347
|
|
|
53
|
12
|
|
|
12
|
1
|
1418
|
sub rand ($self) { $self->{state}->numify / 2**48 } |
|
|
12
|
|
|
|
|
17
|
|
|
|
12
|
|
|
|
|
12
|
|
|
|
12
|
|
|
|
|
52
|
|
|
54
|
|
|
|
|
|
|
|
|
55
|
177
|
|
|
177
|
1
|
6184
|
sub seek ( $self, $n ) { |
|
|
177
|
|
|
|
|
216
|
|
|
|
177
|
|
|
|
|
213
|
|
|
|
177
|
|
|
|
|
153
|
|
|
56
|
177
|
|
|
|
|
531
|
my $steps = Math::BigInt->new("$n"); |
|
57
|
177
|
100
|
100
|
|
|
11067
|
croak "seek() count must be a finite integer, got '$n'" |
|
58
|
|
|
|
|
|
|
if $steps->is_nan || $steps->is_inf; |
|
59
|
172
|
100
|
|
|
|
1922
|
my ( $a, $c ) = $steps->is_negative ? ( $AI, $CI ) : ( $A, $C ); |
|
60
|
172
|
|
|
|
|
1104
|
my ( $pa, $pc ) = _affine_pow( $a, $c, $steps->babs ); |
|
61
|
172
|
|
|
|
|
597
|
$self->{state} = ( $pa * $self->{state} + $pc ) % $M; |
|
62
|
172
|
|
|
|
|
64593
|
return $self; |
|
63
|
|
|
|
|
|
|
} |
|
64
|
|
|
|
|
|
|
|
|
65
|
109
|
|
|
109
|
1
|
38579
|
sub forward ($self) { $self->seek(1) } |
|
|
109
|
|
|
|
|
185
|
|
|
|
109
|
|
|
|
|
103
|
|
|
|
109
|
|
|
|
|
224
|
|
|
66
|
3
|
|
|
3
|
1
|
251
|
sub backward ($self) { $self->seek(-1) } |
|
|
3
|
|
|
|
|
5
|
|
|
|
3
|
|
|
|
|
5
|
|
|
|
3
|
|
|
|
|
8
|
|
|
67
|
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
1; |
|
69
|
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
__END__ |