]>
Commit | Line | Data |
---|---|---|
1d8dc429 | 1 | /* Copyright (C) 1995, 1996 Free Software Foundation, Inc. |
60478656 RM |
2 | This file is part of the GNU C Library. |
3 | Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995. | |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
6 | modify it under the terms of the GNU Library General Public License as | |
7 | published by the Free Software Foundation; either version 2 of the | |
8 | License, or (at your option) any later version. | |
9 | ||
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | Library General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU Library General Public | |
16 | License along with the GNU C Library; see the file COPYING.LIB. If | |
17 | not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
18 | Boston, MA 02111-1307, USA. */ | |
19 | ||
20 | #include <errno.h> | |
21 | #include <stdlib.h> | |
1d8dc429 | 22 | #include <limits.h> |
60478656 RM |
23 | |
24 | ||
25 | /* Global state for non-reentrent functions. */ | |
26 | struct drand48_data __libc_drand48_data; | |
27 | ||
28 | ||
29 | int | |
30 | __drand48_iterate (xsubi, buffer) | |
31 | unsigned short int xsubi[3]; | |
32 | struct drand48_data *buffer; | |
33 | { | |
34 | /* Be generous for the arguments, detect some errors. */ | |
35 | if (xsubi == NULL || buffer == NULL) | |
36 | { | |
37 | errno = EFAULT; | |
38 | return -1; | |
39 | } | |
40 | ||
41 | /* Initialize buffer, if not yet done. */ | |
42 | if (!buffer->init) | |
43 | { | |
1d8dc429 RM |
44 | #if (USHRT_MAX == 0xffffU) |
45 | buffer->a[2] = 0x5; | |
46 | buffer->a[1] = 0xdeec; | |
47 | buffer->a[0] = 0xe66d; | |
48 | #else | |
49 | buffer->a[2] = 0x5deecUL; | |
50 | buffer->a[1] = 0xe66d0000UL; | |
51 | buffer->a[0] = 0; | |
52 | #endif | |
60478656 RM |
53 | buffer->c = 0xb; |
54 | buffer->init = 1; | |
55 | } | |
56 | ||
57 | /* Do the real work. We choose a data type which contains at least | |
58 | 48 bits. Because we compute the modulus it does not care how | |
59 | many bits really are computed. */ | |
60 | ||
61 | if (sizeof (long int) >= 6) | |
62 | { | |
63 | /* The `long' data type is sufficent. */ | |
64 | unsigned long int X, a, result; | |
65 | ||
66 | #define ONE_STEP \ | |
67 | if (sizeof (unsigned short int) == 2) \ | |
68 | { \ | |
69 | X = (xsubi[2] << 16 | xsubi[1]) << 16 | xsubi[0]; \ | |
70 | a = (buffer->a[2] << 16 | buffer->a[1]) << 16 | buffer->a[0]; \ | |
71 | \ | |
72 | result = X * a + buffer->c; \ | |
73 | \ | |
74 | xsubi[0] = result & 0xffff; \ | |
75 | result >>= 16; \ | |
76 | xsubi[1] = result & 0xffff; \ | |
77 | result >>= 16; \ | |
78 | xsubi[2] = result & 0xffff; \ | |
79 | } \ | |
80 | else \ | |
81 | { \ | |
82 | X = xsubi[2] << 16 | xsubi[1] >> 16; \ | |
83 | a = buffer->a[2] << 16 | buffer->a[1] >> 16; \ | |
84 | \ | |
85 | result = X * a + buffer->c; \ | |
86 | \ | |
87 | xsubi[0] = result >> 16 & 0xffffffffl; \ | |
88 | xsubi[1] = result << 16 & 0xffff0000l; \ | |
89 | } | |
90 | ONE_STEP; | |
91 | } | |
92 | else | |
93 | { | |
94 | /* We have to use the `long long' data type. */ | |
95 | unsigned long long int X, a, result; | |
96 | ONE_STEP; | |
97 | } | |
98 | ||
99 | return 0; | |
100 | } |