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 *****************************************************************************/
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)
41 subi
[0] = (x
>> 32) & 0xFFFF;
42 subi
[1] = (x
>> 16) & 0xFFFF;
43 subi
[2] = (x
>> 0) & 0XFFFF;
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;