stream: remove anonymous union
[vlc.git] / compat / nrand48.c
blob67f3fdb8f9fd46efefdc7cf2242e157002d0498c
1 /*****************************************************************************
2 * nrand48.c: POSIX erand48(), jrand48() and nrand48() replacements
3 *****************************************************************************
4 * Copyright © 2010 Rémi Denis-Courmont
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 *****************************************************************************/
21 #ifdef HAVE_CONFIG_H
22 # include <config.h>
23 #endif
25 #include <inttypes.h>
27 static uint64_t iterate48 (unsigned short subi[3])
29 const uint64_t a = UINT64_C(0x5DEECE66D);
30 const unsigned c = 13;
31 const uint64_t mask = UINT64_C(0xFFFFFFFFFFFF); // 48 bits
33 uint64_t x = ((uint64_t)subi[0] << 32)
34 | ((uint32_t)subi[1] << 16)
35 | subi[2];
37 x *= a;
38 x += c;
39 x &= mask;
41 subi[0] = (x >> 32) & 0xFFFF;
42 subi[1] = (x >> 16) & 0xFFFF;
43 subi[2] = (x >> 0) & 0XFFFF;
45 return x;
48 double erand48 (unsigned short subi[3])
50 uint64_t r = iterate48 (subi);
51 return ((double)r) / 281474976710655.;
54 long jrand48 (unsigned short subi[3])
56 return ((int64_t)iterate48 (subi)) >> 16;
59 long nrand48 (unsigned short subi[3])
61 return iterate48 (subi) >> 17;