How to generate random uint64 values

22 visualizzazioni (ultimi 30 giorni)
MATLAB supports uint64. I need to generate random uint64 values, e.g., greater than (2^52-1) which is the largest that can be represented as a double with its 52-bit mantissa. (Or is it 53 bit?) In any case, I want to be able to go all the way up to intmax('uint64') if needed. But there does not seem to be any support for this. The following command produces an error, but this is essentially what I'm looking for...
r = randi(intmax('uint64'),100,1,'uint64')
Presumably I could generate two 'uint32' arrays and convert them to uint64, but I'm wondering if there are any builtin ideas.
I'm currently using MATLAB R2020b.
Thanks in advance for any ideas.
  1 Commento
Tammy Kolda
Tammy Kolda il 13 Giu 2021
I realize my first example was too specific. I'd really like to be about to do...
r = randi(maxval,100,1,'uint64')
where maxval is a value greater than 2^52 (max integer representable by double) and less than 2^64-1.

Accedi per commentare.

Risposta accettata

Tammy Kolda
Tammy Kolda il 15 Giu 2021
Here is a version that attempts to properly account for the difference in probability for the last "hi" bin. Admittedly, this probability is very small, so I don't expect much practical impact.
function R = randi64(maxval,sz)
%RANDI64 Generate random numbers between 1 and a given 'uint64' value.
% Total number of random numbers desired
N = prod(sz);
% We work on generating values between 0 and maxval-1, and then add 1 at
% the end to make the indices one-based.
zmaxval = maxval - 1;
if zmaxval < uint64(2^52-1)
% By default, randi generates doubles with mantissas of 52 bits, so we
% should be able to safely generate all integers between zero and
% 2^52-1, and then cast these to 64-bit integers.
R = randi([0 zmaxval], N, 1);
R = uint64(R);
else
% The logic here is that we split the random number into two 32-bit
% parts, referred to as "hi" and "lo".
nbits = 32;
zmaxval_hi = idivide(zmaxval,uint64(2^nbits),'floor'); % number of hi bins
zmaxval_lo1 = mod(zmaxval,2^nbits); % number of lo bins for last hi bin
zmaxval_lo0 = 2^nbits-1; % number of lo bins for every hi bin but the last
% We need to handle the last high bin specially because its probability
% is not equal to the other bins. We figure out its probability and
% separate the random numbers into those that are in the last bin (lo1)
% and those that aren't (lo0).
p_last_hi = (zmaxval_lo1 + 1) / maxval;
last_bin = rand(N,1) <= p_last_hi; % True if in last bin
R_hi = zeros(N,1);
R_lo = zeros(N,1);
% First, let's deal with the last "hi" bin. The "lo" values in this bin
% don't go all the way up to 2^32. It's generally a very small
% probability of being in the very last bin!
n1 = sum(last_bin);
if n1 > 0
R_hi(last_bin) = zmaxval_hi;
R_lo(last_bin) = randi([0,zmaxval_lo1],n1,1);
end
% The rest is generated normally, i.e., the hi bin is between 0 and the
% next to last bin, and the lo bin can take all 2^32 values.
n0 = N-n1;
if n0 > 0
R_hi(~last_bin) = randi([0,zmaxval_hi-1],n0,1);
R_lo(~last_bin) = randi([0,zmaxval_lo0],n0,1);
end
% Now combine the hi and lo bits.
R = uint64(R_hi)*(2^nbits) + uint64(R_lo);
end
R = 1+R;
R = reshape(R,[sz 1 1]);

Più risposte (2)

Bruno Luong
Bruno Luong il 12 Giu 2021
I can't see why you are reluctant to generate 2 x 4 bytes
r = typecast(randi(intmax('uint32'),2*100,1,'uint32'),'uint64')
  1 Commento
Tammy Kolda
Tammy Kolda il 13 Giu 2021
Thanks. Yes, this would work for generating arbitrary 64-bit numbers, but I want them within a specified range. I realize that my example was too specific, so I made the second example more explicit on this front.

Accedi per commentare.


Bruno Luong
Bruno Luong il 14 Giu 2021
Modificato: Bruno Luong il 14 Giu 2021
maxval = int64(2^60);
n = 100;
twop32 = 2^32;
q = double(maxval/twop32);
hi = floor(q*rand(1,n));
himax = floor(q);
lomax = twop32 + zeros(1,n);
lomax(hi == himax) = mod(maxval,twop32);
lo = ceil(lomax.*rand(1,n));
r = uint64(lo) + uint64(twop32)*uint64(hi);
disp(r)
Columns 1 through 9 135806180693687862 215588009524488332 117408898232367499 1099547910952985418 515704523293082877 635779628928771119 870758931710308107 717034553376676578 436155041046080048 Columns 10 through 18 831983435716745994 183691261160545909 213626557346699709 420265566427008490 333345668586881853 1095488061805884963 909014354025207880 1108539113226662640 939453617172184878 Columns 19 through 27 23094351282361364 920093773963311158 816012561579772331 370077997904541368 402750038699513673 146148483590873451 606532791893970232 482952764136759671 9930734750916776 Columns 28 through 36 281354922787510695 993355938895232876 695269422713423043 287057466906553522 194141971359035327 1001184774562317014 814656455861663548 1054089989684188170 552028415015681857 Columns 37 through 45 144688093981716528 918137351964135000 294836881770643453 201123859973696442 495467446763425659 235704339590183073 655981081202190675 40055980366272701 1125155383894296590 Columns 46 through 54 303545116848030165 734151138404125667 66237703055042872 667659256453775614 914429097626427606 906168068126356875 100670814079079238 523347783488679820 641796739168669154 Columns 55 through 63 186347393512288866 790941465961570732 551777245086872755 229302325638874745 107006844765212189 98817756260889654 758563880569993897 808445962833371388 212622459636366724 Columns 64 through 72 753523529308653205 324057918538782265 882935355984717570 34742708633763330 176893055534676850 428055358546579981 280459802992240053 21545503214921165 506300771545612170 Columns 73 through 81 102056057053017081 1042711114925152956 648010537940203959 713373207897902354 254507842659846687 626984727858006330 1088221806844931303 182190604819604693 973197486867315423 Columns 82 through 90 932028522436527382 293302202132222023 215125611009428340 1040104476788689687 612598602262196408 466329434892185869 367053937742804098 971042021906830607 1113307166134750126 Columns 91 through 99 434308117745485748 188866236382430955 249276385400741269 1018378345009340061 74096166918309813 544511574990135771 884471630599796226 495738373977466003 1076141640047671089 Column 100 770764230572194630
  1 Commento
Tammy Kolda
Tammy Kolda il 15 Giu 2021
There are a few nuances with 1-based versus 0-based and ensuring that the probabilities are uniform. I include some code below.

Accedi per commentare.

Prodotti


Release

R2020b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by