~ubuntu-branches/debian/sid/pgadmin3/sid

« back to all changes in this revision

Viewing changes to pgadmin/pgscript/utilities/m_apm/mapm_rnd.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Gerfried Fuchs
  • Date: 2009-07-30 12:27:16 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20090730122716-fddbh42on721bbs2
Tags: 1.10.0-1
* New upstream release.
* Adjusted watch file to match release candidates.
* Updated to Standards-Version 3.8.2:
  - Moved to Section: database.
  - Add DEB_BUILD_OPTIONS support for parallel building.
  - Move from findstring to filter suggestion for DEB_BUILD_OPTIONS parsing.
* pgagent got split into its own separate source package by upstream.
* Exclude Docs.vcproj from installation.
* Move doc-base.enus from pgadmin3 to pgadmin3-data package, the files are
  in there too.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/* 
 
3
 *  M_APM  -  mapm_rnd.c
 
4
 *
 
5
 *  Copyright (C) 1999 - 2007   Michael C. Ring
 
6
 *
 
7
 *  Permission to use, copy, and distribute this software and its
 
8
 *  documentation for any purpose with or without fee is hereby granted,
 
9
 *  provided that the above copyright notice appear in all copies and
 
10
 *  that both that copyright notice and this permission notice appear
 
11
 *  in supporting documentation.
 
12
 *
 
13
 *  Permission to modify the software is granted. Permission to distribute
 
14
 *  the modified code is granted. Modifications are to be distributed by
 
15
 *  using the file 'license.txt' as a template to modify the file header.
 
16
 *  'license.txt' is available in the official MAPM distribution.
 
17
 *
 
18
 *  This software is provided "as is" without express or implied warranty.
 
19
 */
 
20
 
 
21
/*
 
22
 *
 
23
 *      This file contains the Random Number Generator function.
 
24
 *
 
25
 */
 
26
 
 
27
#include "pgAdmin3.h"
 
28
#include "pgscript/utilities/mapm-lib/m_apm_lc.h"
 
29
 
 
30
#ifndef _HAVE_NI_LABWIN_CVI_
 
31
#ifdef MSDOS
 
32
#include <time.h>
 
33
#include <sys/timeb.h>
 
34
#else
 
35
#include <sys/time.h>
 
36
extern  void    M_get_microsec(unsigned long *, long *);
 
37
#endif
 
38
#endif
 
39
 
 
40
#ifdef _HAVE_NI_LABWIN_CVI_
 
41
#include <time.h>
 
42
#include <utility.h>
 
43
#include <ansi/math.h>
 
44
#endif
 
45
 
 
46
extern  void    M_reverse_string(char *);
 
47
extern  void    M_get_rnd_seed(M_APM);
 
48
 
 
49
static  M_APM   M_rnd_aa;
 
50
static  M_APM   M_rnd_mm;
 
51
static  M_APM   M_rnd_XX;
 
52
static  M_APM   M_rtmp0;
 
53
static  M_APM   M_rtmp1;
 
54
 
 
55
static  int     M_firsttime2 = TRUE;
 
56
 
 
57
/*
 
58
        Used Knuth's The Art of Computer Programming, Volume 2 as
 
59
        the basis. Assuming the random number is X, compute
 
60
        (where all the math is performed on integers) :
 
61
 
 
62
        X = (a * X + c) MOD m
 
63
 
 
64
        From Knuth:
 
65
 
 
66
        'm' should be large, at least 2^30 : we use 1.0E+15
 
67
 
 
68
        'a' should be between .01m and .99m and not have a simple
 
69
        pattern. 'a' should not have any large factors in common 
 
70
        with 'm' and (since 'm' is a power of 10) if 'a' MOD 200 
 
71
        = 21 then all 'm' different possible values will be 
 
72
        generated before 'X' starts to repeat.
 
73
 
 
74
        We use 'a' = 716805947629621.
 
75
 
 
76
        This is a prime number and also meets 'a' MOD 200 = 21. 
 
77
        Commented out below are many potential multipliers that 
 
78
        are all prime and meet 'a' MOD 200 = 21.
 
79
 
 
80
        There are few restrictions on 'c' except 'c' can have no
 
81
        factor in common with 'm', hence we set 'c' = 'a'.
 
82
 
 
83
        On the first call, the system time is used to initialize X.
 
84
*/
 
85
 
 
86
/*
 
87
 *  the following constants are all potential multipliers. they are
 
88
 *  all prime numbers that also meet the criteria of NUM mod 200 = 21.
 
89
 */
 
90
 
 
91
/*
 
92
439682071525421   439682071528421   439682071529221   439682071529821
 
93
439682071530421   439682071532021   439682071538821   439682071539421
 
94
439682071540021   439682071547021   439682071551221   439682071553821
 
95
439682071555421   439682071557221   439682071558021   439682071558621
 
96
439682071559821   439652381461621   439652381465221   439652381465621
 
97
439652381466421   439652381467421   439652381468621   439652381470021
 
98
439652381471221   439652381477021   439652381484221   439652381488421
 
99
439652381491021   439652381492021   439652381494021   439652381496821
 
100
617294387035621   617294387038621   617294387039221   617294387044421
 
101
617294387045221   617294387048621   617294387051621   617294387051821
 
102
617294387053621   617294387058421   617294387064221   617294387065621
 
103
617294387068621   617294387069221   617294387069821   617294387070421
 
104
617294387072021   617294387072621   617294387073821   617294387076821
 
105
649378126517621   649378126517821   649378126518221   649378126520821
 
106
649378126523821   649378126525621   649378126526621   649378126528421
 
107
649378126529621   649378126530821   649378126532221   649378126533221
 
108
649378126535221   649378126539421   649378126543621   649378126546021
 
109
649378126546421   649378126549421   649378126550821   649378126555021
 
110
649378126557421   649378126560221   649378126561621   649378126562021
 
111
649378126564621   649378126565821   672091582360421   672091582364221
 
112
672091582364621   672091582367021   672091582368421   672091582369021
 
113
672091582370821   672091582371421   672091582376821   672091582380821
 
114
716805243983221   716805243984821   716805947623621   716805947624621
 
115
716805947629021   716805947629621   716805947630621   716805947633621
 
116
716805947634221   716805947635021   716805947635621   716805947642221
 
117
*/
 
118
 
 
119
/****************************************************************************/
 
120
void    M_free_all_rnd()
 
121
{
 
122
if (M_firsttime2 == FALSE)
 
123
  {
 
124
   m_apm_free(M_rnd_aa);
 
125
   m_apm_free(M_rnd_mm);
 
126
   m_apm_free(M_rnd_XX);
 
127
   m_apm_free(M_rtmp0);
 
128
   m_apm_free(M_rtmp1);
 
129
 
 
130
   M_firsttime2 = TRUE;
 
131
  }
 
132
}
 
133
/****************************************************************************/
 
134
void    m_apm_set_random_seed(char *ss)
 
135
{
 
136
M_APM   btmp;
 
137
 
 
138
if (M_firsttime2)
 
139
  {
 
140
   btmp = M_get_stack_var();
 
141
   m_apm_get_random(btmp);
 
142
   M_restore_stack(1);
 
143
  }
 
144
 
 
145
m_apm_set_string(M_rnd_XX, ss);
 
146
}
 
147
/****************************************************************************/
 
148
/*
 
149
 *  compute X = (a * X + c) MOD m       where c = a
 
150
 */
 
151
void    m_apm_get_random(M_APM mrnd)
 
152
{
 
153
 
 
154
if (M_firsttime2)         /* use the system time as the initial seed value */
 
155
  {
 
156
   M_firsttime2 = FALSE;
 
157
   
 
158
   M_rnd_aa = m_apm_init();
 
159
   M_rnd_XX = m_apm_init();
 
160
   M_rnd_mm = m_apm_init();
 
161
   M_rtmp0  = m_apm_init();
 
162
   M_rtmp1  = m_apm_init();
 
163
 
 
164
   /* set the multiplier M_rnd_aa and M_rnd_mm */
 
165
   
 
166
   m_apm_set_string(M_rnd_aa, "716805947629621");
 
167
   m_apm_set_string(M_rnd_mm, "1.0E15");
 
168
 
 
169
   M_get_rnd_seed(M_rnd_XX);
 
170
  }
 
171
 
 
172
m_apm_multiply(M_rtmp0, M_rnd_XX, M_rnd_aa);
 
173
m_apm_add(M_rtmp1, M_rtmp0, M_rnd_aa);
 
174
m_apm_integer_div_rem(M_rtmp0, M_rnd_XX, M_rtmp1, M_rnd_mm);
 
175
m_apm_copy(mrnd, M_rnd_XX);
 
176
mrnd->m_apm_exponent -= 15;
 
177
}
 
178
/****************************************************************************/
 
179
void    M_reverse_string(char *s)
 
180
{
 
181
int     ct;
 
182
char    ch, *p1, *p2;
 
183
 
 
184
if ((ct = strlen(s)) <= 1)
 
185
  return;
 
186
 
 
187
p1 = s;
 
188
p2 = s + ct - 1;
 
189
ct /= 2;
 
190
 
 
191
while (TRUE)
 
192
  {
 
193
   ch    = *p1;
 
194
   *p1++ = *p2;
 
195
   *p2-- = ch;
 
196
 
 
197
   if (--ct == 0)
 
198
     break;
 
199
  }
 
200
}
 
201
/****************************************************************************/
 
202
 
 
203
#ifndef _HAVE_NI_LABWIN_CVI_
 
204
 
 
205
#ifdef MSDOS
 
206
 
 
207
/****************************************************************************/
 
208
/*
 
209
 *  for DOS / Win 9x/NT systems : use 'ftime' 
 
210
 */
 
211
void    M_get_rnd_seed(M_APM mm)
 
212
{
 
213
int              millisec;
 
214
time_t           timestamp;
 
215
unsigned long    ul;
 
216
char             ss[32], buf1[48], buf2[32];
 
217
struct timeb     timebuffer;
 
218
M_APM            atmp;
 
219
 
 
220
atmp = M_get_stack_var();
 
221
 
 
222
ftime(&timebuffer);
 
223
 
 
224
millisec  = (int)timebuffer.millitm;    
 
225
timestamp = timebuffer.time;
 
226
ul        = (unsigned long)(timestamp / 7);
 
227
ul       += timestamp + 537;
 
228
strcpy(ss,ctime(&timestamp));        /* convert to string and copy to ss */
 
229
 
 
230
sprintf(buf1,"%d",(millisec / 10));
 
231
sprintf(buf2,"%lu",ul);
 
232
 
 
233
ss[0] = ss[18];
 
234
ss[1] = ss[17];
 
235
ss[2] = ss[15];
 
236
ss[3] = ss[14];
 
237
ss[4] = ss[12];
 
238
ss[5] = ss[11];
 
239
ss[6] = ss[9];
 
240
ss[7] = ss[23];
 
241
ss[8] = ss[20];
 
242
ss[9] = '\0';
 
243
 
 
244
M_reverse_string(buf2);
 
245
strcat(buf1,buf2);
 
246
strcat(buf1,ss);
 
247
 
 
248
m_apm_set_string(atmp, buf1);
 
249
atmp->m_apm_exponent = 15;
 
250
m_apm_integer_divide(mm, atmp, MM_One);
 
251
 
 
252
M_restore_stack(1);
 
253
}
 
254
/****************************************************************************/
 
255
 
 
256
#else
 
257
 
 
258
/****************************************************************************/
 
259
/*
 
260
 *  for unix systems : use 'gettimeofday'
 
261
 */
 
262
void    M_get_rnd_seed(M_APM mm)
 
263
{
 
264
unsigned long    sec3;
 
265
long             usec3;
 
266
char             buf1[32], buf2[32];
 
267
M_APM            atmp;
 
268
 
 
269
atmp = M_get_stack_var();
 
270
M_get_microsec(&sec3,&usec3);
 
271
 
 
272
sprintf(buf1,"%ld",usec3);
 
273
sprintf(buf2,"%lu",sec3);
 
274
M_reverse_string(buf2);
 
275
strcat(buf1,buf2);
 
276
 
 
277
m_apm_set_string(atmp, buf1);
 
278
atmp->m_apm_exponent = 15;
 
279
m_apm_integer_divide(mm, atmp, MM_One);
 
280
 
 
281
M_restore_stack(1);
 
282
}
 
283
/****************************************************************************/
 
284
void     M_get_microsec(unsigned long *sec, long *usec)
 
285
{
 
286
struct timeval time_now;           /* current time for elapsed time check */
 
287
struct timezone time_zone;         /* time zone for gettimeofday call     */
 
288
 
 
289
gettimeofday(&time_now, &time_zone);                  /* get current time */
 
290
 
 
291
*sec  = time_now.tv_sec;
 
292
*usec = time_now.tv_usec;
 
293
}
 
294
/****************************************************************************/
 
295
 
 
296
#endif
 
297
#endif
 
298
 
 
299
#ifdef _HAVE_NI_LABWIN_CVI_
 
300
 
 
301
/****************************************************************************/
 
302
/*
 
303
 *  for National Instruments LabWindows CVI
 
304
 */
 
305
 
 
306
void    M_get_rnd_seed(M_APM mm)
 
307
{
 
308
double           timer0;
 
309
int              millisec;
 
310
char             *cvi_time, *cvi_date, buf1[64], buf2[32];
 
311
M_APM            atmp;
 
312
 
 
313
atmp = M_get_stack_var();
 
314
 
 
315
cvi_date = DateStr();
 
316
cvi_time = TimeStr();
 
317
timer0   = Timer();
 
318
 
 
319
/*
 
320
 *  note that Timer() is not syncronized to TimeStr(),
 
321
 *  but we don't care here since we are just looking
 
322
 *  for a random source of digits.
 
323
 */
 
324
 
 
325
millisec = (int)(0.01 + 1000.0 * (timer0 - floor(timer0)));
 
326
 
 
327
sprintf(buf1, "%d", millisec);
 
328
 
 
329
buf2[0]  = cvi_time[6]; /* time format: "HH:MM:SS" */
 
330
buf2[1]  = cvi_time[7];
 
331
buf2[2]  = cvi_time[3];
 
332
buf2[3]  = cvi_time[4];
 
333
buf2[4]  = cvi_time[0];
 
334
buf2[5]  = cvi_time[1];
 
335
 
 
336
buf2[6]  = cvi_date[3]; /* date format: "MM-DD-YYYY" */
 
337
buf2[7]  = cvi_date[4];
 
338
buf2[8]  = cvi_date[0];
 
339
buf2[9]  = cvi_date[1];
 
340
buf2[10] = cvi_date[8];
 
341
buf2[11] = cvi_date[9];
 
342
buf2[12] = cvi_date[7];
 
343
 
 
344
buf2[13] = '4';
 
345
buf2[14] = '7';
 
346
buf2[15] = '\0';
 
347
 
 
348
strcat(buf1, buf2);
 
349
 
 
350
m_apm_set_string(atmp, buf1);
 
351
atmp->m_apm_exponent = 15;
 
352
m_apm_integer_divide(mm, atmp, MM_One);
 
353
 
 
354
M_restore_stack(1);
 
355
}
 
356
 
 
357
#endif
 
358
 
 
359
/****************************************************************************/
 
360