Re: how to get a 64bit random number with rand() ?
by Tux (Canon) on Mar 21, 2018 at 15:02 UTC
|
Note that this is not a (real) answer to your question, but some (side)notes ...
If you use use strict; use warnings;, you would get this warning:
Hexadecimal number > 0xffffffff non-portable at test.pl line 9
Of course with the name of your script and the location of that 0xf...
But when using large numbers like that, I'd advice to use decimal notation instead of hexadecimal, just for portability.
Than it depends on your perl being compiled with -Duse64bitint or another (default) option that causes IV's (perl internal integers) allow 64bit data. That is easy to check though:
$ perl -V:ivsize
ivsize='8';
$ perl -wle'print 1152921504606846975'
1152921504606846975
$ perl -wle'printf "%x\n", 1152921504606846975'
fffffffffffffff
Compare to a perl with 32bit IV's:
$ gperl32 -V:ivsize
ivsize='4';
$ gperl32 -wle'print 1152921504606846975'
1.15292150460685e+18
$ gperl32 -wle'printf "%x\n", 1152921504606846975'
ffffffff
Maybe this helps on the short term:
use 5.18.2;
use warnings;
$|++;
srand 54321;
say "One rand";
for (1 .. 20) {
my $n = int rand 1152921504606846975;
printf "\r%064b %016X\n", $n, $n;
}
say "Two rands";
for (1 .. 20) {
my ($n1, $n2) = map { int rand 0xffff_ffff } 0, 1;
my $n = unpack "Q>", pack "L>L>", $n1, $n2;
printf "\r%064b %016X\n", $n, $n;
}
->
One rand
0000000001011110010111000001101110010101000100000000111111111111 005E5
+C1B95100FFF
0000110011101111101010000101100110100110001101110111111111111111 0CEFA
+859A6377FFF
0000001100101010000101011010101110100010101000100010111111111111 032A1
+5ABA2A22FFF
0000011011010000111100010101011000110110001011110001111111111111 06D0F
+156362F1FFF
0000110100101100101001111001010011101000110100010100111111111111 0D2CA
+794E8D14FFF
0000010111010101110101111110100011101110111111111011111111111111 05D5D
+7E8EEFFBFFF
0000000100000101000100010010110010001001011001010110111111111111 01051
+12C89656FFF
0000111111000110001001000000101011100010110100010101111111111111 0FC62
+40AE2D15FFF
0000010010010000101010101010111100101111011001101000111111111111 0490A
+AAF2F668FFF
0000110010001101100001001001101000010100000010111111111111111111 0C8D8
+49A140BFFFF
0000110100001100110001101010110101010001000111001010111111111111 0D0CC
+6AD511CAFFF
0000001010011101011001011011110110001111010101111001111111111111 029D6
+5BD8F579FFF
0000000000110000111000100000011001000010000011111100111111111111 0030E
+206420FCFFF
0000010100111111100010001111100000010101100111000011111111111111 053F8
+8F8159C3FFF
0000010010011010111000001001011010010101000001111110111111111111 049AE
+0969507EFFF
0000010011101110110111110111001111010110000000011101111111111111 04EED
+F73D601DFFF
0000011011011111100000001001001001001110000011010000111111111111 06DF8
+0924E0D0FFF
0000011101111101110010000101010110110111111100000111111111111111 077DC
+855B7F07FFF
0000111011000101111100000111011101100100011001110010111111111111 0EC5F
+07764672FFF
0000110101111000101000011100101010110101000100000001111111111111 0D78A
+1CAB5101FFF
Two rands
0110111011001000100010011001000010011000011110001101000001011011 6EC88
+9909878D05B
1000011111110001011001111000011100001110111101111100100010001100 87F16
+7870EF7C88C
1011000100011111101001110011000101100011010110101001110101110011 B11FA
+731635A9D73
1110001111001110010011000011100101001011111110010101000101001010 E3CE4
+C394BF9514A
1110001001010010001001100101001001010011000011001111000101011100 E2522
+652530CF15C
1111001101101100101000011110101010011011111101000110000011101110 F36CA
+1EA9BF460EE
0011110101110110001011001101001110011110001101000111010011011010 3D762
+CD39E3474DA
1110010101011100001011111011000101010100110100110110010100001010 E55C2
+FB154D3650A
0001000100010110101111100011110000100000111001010100000101000011 1116B
+E3C20E54143
1001010000111100010000111000111010100100101100111001100011011000 943C4
+38EA4B398D8
1101101010011010011001010001001100110100111010100111000101000001 DA9A6
+51334EA7141
0101010111110100011011011110000100101100011001110000110110100100 55F46
+DE12C670DA4
0101011101011010100111010111001010011010111011110111100111010110 575A9
+D729AEF79D6
1110111111111001000000000001111001110000011001000101010101100110 EFF90
+01E70645566
0111010100101110110101001101001101110110111101111000111110100000 752ED
+4D376F78FA0
1010110111001100010000101100000111011001001100111011001110110010 ADCC4
+2C1D933B3B2
0110010100000111000100110010110101100110100011111001110001011110 65071
+32D668F9C5E
1000010010001000100101101000000010100011000000111111100011010100 84889
+680A303F8D4
1001011101011111101000010100010000010010111010111000100010110010 975FA
+14412EB88B2
1001001001001110111101001100000001101010000011110110101100110110 924EF
+4C06A0F6B36
Enjoy, Have FUN! H.Merijn
| [reply] [d/l] [select] |
Re: how to get a 64bit random number with rand() ?
by thanos1983 (Parson) on Mar 21, 2018 at 12:35 UTC
|
Hello iglake,
Take a look on an older question with multiple different answers to your problem 64 bit random numbers.
Hope this helps, BR.
Seeking for Perl wisdom...on the process of learning...not there...yet!
| [reply] [d/l] [select] |
|
| [reply] |
Re: how to get a 64bit random number with rand() ?
by BrowserUk (Patriarch) on Mar 21, 2018 at 18:06 UTC
|
Here's one way on a 64-bit capable build, provided your prng can produce at least 8-bit rands:
sub rand64{ unpack 'Q', pack 'C8', map rand(256), 1 .. 8; }
for(1..10){
my $rand64 = rand64();
printf "%64s %16s %I64U\n",
unpack( 'b64', pack( 'Q', $rand64 ) ),
unpack( 'H16', pack( 'Q', $rand64 ) ),
$rand64;
}
1010111111000000011010001011001101101010011001011110100101011101 f5031
+6cd56a697ba 13445398104276075509
1011010011110001101111011011100010001000001100000001011101111110 2d8fb
+d1d110ce87e 9144572311028731693
1100000000001011011000101111011110001110110110001110000000101001 03d04
+6ef711b0794 10666524418609958915
1000101001111110010101010010011101000111000011010101100000110110 517ea
+ae4e2b01a6c 7789732994036170321
0010010000011010010011110001100000111110001011000100110111110011 2458f
+2187c34b2cf 14966082219304704036
1111100110000001010110000110011011011100010010001001000100101101 9f811
+a663b1289b4 13008949044961771935
1001111000111111101110010111001111010011011111001110101110101100 79fc9
+dcecb3ed735 3879638649068715129
0000010011010010001110011101111101011111001001110101001011100101 204b9
+cfbfae44aa7 12054699119224834848
1110111000010100001101010110011111010011111011000100010111100011 7728a
+ce6cb37a2c7 14385121508662716535
0011110011100110111011000101100110100100100110101101011101011000 3c673
+79a2559eb1a 1939742082549114684
With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
In the absence of evidence, opinion is indistinguishable from prejudice.
Suck that fhit
| [reply] [d/l] |
Re: how to get a 64bit random number with rand() ?
by LanX (Saint) on Mar 21, 2018 at 12:44 UTC
|
What's wrong with combining two 32bit random numbers?
| [reply] |
|
yes that is what I ended up doing, thanks !
| [reply] |
|
| [reply] |
Re: how to get a 64bit random number with rand() ?
by bliako (Monsignor) on Mar 22, 2018 at 14:55 UTC
|
Can't agree more with BrowserUk.
Whatever you do always verify the statistical distribution of your method for producing random numbers.
In order to do that you need to produce a large bunch of these random numbers and plot a histogram
of their values or, much more accurate, run a test for verifying the distribution. Here is a test for a discrete distribution, e.g. dice numbers: https://stackoverflow.com/questions/21204733/a-better-chi-square-test-for-perl
Perl's rand() will, in theory, produce random numbers drawn from a uniform distribution: all values from 0 to 1 have equal probability to appear. The histogram of such a distribution is more-or-less a flat line (the equal probabilities). Provided that you draw *a lot* of random numbers you will be approximating that.
Now if you *add* two rand() values in order, for example, to get a 64-bit random value you will find that the histogram of the numbers you get is not a flat line anymore but resembling more of a bell-curve, the trademark of a Gaussian (aka Normal) distribution. I would love to play poker against a machine which uses this method ...
Here is some code to demonstrate this:
#!/usr/bin/env perl
use strict;
use warnings;
use Statistics::Histogram;
my $num_bins = 50;
my $use_linear_axes = 1;
srand(1234);
### Produce a lot of random numbers:
# 1) expecting a flat line (uniform distribution):
my @x = map { rand() } 1..1000000;
# 2) sum of two rand() to get larger random number
# - I am getting larger numbers and I am expecting a flat line.
# - you wanna bet?
my @y = map { rand()+rand() } 1..1000000;
# Now draw the histograms of obtained random numbers:
# 1) perl's rand is quite uniform, I see a flat line:
print Statistics::Histogram::get_histogram(\@x, $num_bins, $use_linear
+_axes);
# 2) !!ouch - that hurt !!
print Statistics::Histogram::get_histogram(\@y, $num_bins, $use_linear
+_axes);
Bottomline: I always wanted to ask Einsten to clarify whether "dice" in his famous "God does not play dice" is plurar or singular. I guess I will never know although maybe 60 years ago dice did have the singular of die. If God plays with a single dice his or her distributions will be Uniform (the flat lines). However, if God plays with two dice (and sums up the two rands) his/her distributions will be Gaussian (the bell shape) and that makes a lot of difference for the Universe.
bliako | [reply] [d/l] |
|
I always wanted to ask Einsten to clarify whether "dice" in his famous "God does not play dice" is plurar or singular.
God will have an infinite-sided die (a sphere), and can therefore get any real number with only 1 throw.
-QM
--
Quantum Mechanics: The dreams stuff is made of
| [reply] |
|
| [reply] |
|
|
the distribution the number is drawn from is what counts. Uniform then unless the sphere is not honest.
It is obvious that Einstein thought God to be singular (as per LanX) for the simple reason that a multitude of Gods would probably combine their random numbers which would result in a Gaussian again...
Polytheism results in an extremely biased (and predictable) Universe.
bliako
| [reply] |
|
|
|
AFAIK he said "Gott würfelt nicht!" *
"würfeln" is a verb for playing with dice without numerus for the object. ("God is not dicing!"° if you want)
His English was so rudimentary, that his assistants in Princeton had to be fluent in German.
But I'm sure he supposed God to be singular...
*) according to wikipedia from 1926
°) "to dice" exists at least in Shakespearian English and Game of Thrones.
| [reply] |
|
Now if you *add* two rand() values in order, for example, to get a 64-bit random value
You have omitted a little bit of detail that was not omitted in BrowserUk's warning: the context was combining two 32-bit values to obtain a 64-bit value.
Can you please elaborate on how it is possible to ADD two 32-bit numbers — of any origin, not necessarily rand() — and arrive at a value in 64-bit range?
| [reply] |
|
my point lies somewhere else, but you are correct:
adding two 32-bit numbers may get you to, at most, a 33-bit number.
Read that as "add thirty-two 32-bit rands()" (Gaussian distribution) or "multiply two 32-bit rands()" (uniform-product distribution).
Adding is just one form of combining two values but it's perfect to demonstrate the caveats of "combining" rand()s and that not all forms of "combining" rand()s lead to the desirable effect.
bliako
| [reply] |
|
Re: how to get a 64bit random number with rand() ?
by Anonymous Monk on Mar 21, 2018 at 20:32 UTC
|
If you're on Linux and need a block of randomness of decent quality, you may defer to system's random generator. Tools like shuf use the same under the hood.
#! /usr/bin/perl
use strict;
use warnings;
sub rnd_bytes {
local $/ = \( shift || 8 );
open my $fh, '<', '/dev/urandom';
scalar <$fh>
}
for my $n (unpack "Q*", rnd_bytes(20 * 8)) {
printf "\r%064b %016X\n",$n,$n;
}
| [reply] [d/l] |
Re: how to get a 64bit random number with rand() ?
by Anonymous Monk on Mar 21, 2018 at 13:18 UTC
|
It sounds to me like you need a cryptographically secure PRNG such as Math::Random::Secure or Crypt::Random . . . "Garden variety" PRNGs are good enough for statistics sampling only, or the occasional game. | [reply] |
|
sundial, there is nothing in the OPs post that suggests, hints or alludes to a requirement for the huge additional costs and complexity of a cryptographic PRNG.
You're just making shit up again, and spewing out regurgitated snippets of advice by other people, that you obviously have no understanding of.
With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
In the absence of evidence, opinion is indistinguishable from prejudice.
Suck that fhit
| [reply] |
|
Let's be fair. 'Anonymous Monk' has alerted the OP that in some cases, more powerful tools are required and are available. Potentially, this could be the most important post so far.
| [reply] |
|
|
A reply falls below the community's threshold of quality. You may see it by logging in.
|