public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "fxcoudert at gcc dot gnu dot org" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug libfortran/32812] random_seed and date_and_time
Date: Fri, 10 Aug 2007 19:04:00 -0000	[thread overview]
Message-ID: <20070810190427.12413.qmail@sourceware.org> (raw)
In-Reply-To: <bug-32812-10391@http.gcc.gnu.org/bugzilla/>



------- Comment #2 from fxcoudert at gcc dot gnu dot org  2007-08-10 19:04 -------
I guess we have to scramble the seed given by the user, something like this:

Index: intrinsics/random.c
===================================================================
--- intrinsics/random.c (revision 127331)
+++ intrinsics/random.c (working copy)
@@ -32,6 +32,7 @@ Boston, MA 02110-1301, USA.  */
 #include "config.h"
 #include "libgfortran.h"
 #include <gthr.h>
+#include <string.h>

 extern void random_r4 (GFC_REAL_4 *);
 iexport_proto(random_r4);
@@ -639,6 +640,29 @@ arandom_r16 (gfc_array_r16 *x)

 #endif

+
+
+static void
+scramble_seed (unsigned char *dest, unsigned char *src, int size)
+{
+  int i;
+
+  for (i = 0; i < size; i++)
+    dest[(i % 2) * (size / 2) + i / 2] = src[i];
+}
+
+
+static void
+unscramble_seed (unsigned char *dest, unsigned char *src, int size)
+{
+  int i;
+
+  for (i = 0; i < size; i++)
+    dest[i] = src[(i % 2) * (size / 2) + i / 2];
+}
+
+
+
 /* random_seed is used to seed the PRNG with either a default
    set of seeds or user specified set of seeds.  random_seed
    must be called with no argument or exactly one argument.  */
@@ -647,6 +671,7 @@ void
 random_seed (GFC_INTEGER_4 *size, gfc_array_i4 *put, gfc_array_i4 *get)
 {
   int i;
+  unsigned char seed[4*kiss_size];

   __gthread_mutex_lock (&random_lock);

@@ -654,10 +679,8 @@ random_seed (GFC_INTEGER_4 *size, gfc_ar
     {
       /* From the standard: "If no argument is present, the processor assigns
          a processor-dependent value to the seed."  */
-
       for (i=0; i<kiss_size; i++)
        kiss_seed[i] = kiss_default_seed[i];
-
     }

   if (size != NULL)
@@ -673,9 +696,15 @@ random_seed (GFC_INTEGER_4 *size, gfc_ar
       if (((put->dim[0].ubound + 1 - put->dim[0].lbound)) < kiss_size)
         runtime_error ("Array size of PUT is too small.");

-      /*  This code now should do correct strides.  */
+      /*  We copy the seed given by the user.  */
       for (i = 0; i < kiss_size; i++)
-       kiss_seed[i] =(GFC_UINTEGER_4) put->data[i * put->dim[0].stride];
+       memcpy (seed + i * sizeof(GFC_UINTEGER_4),
+               &(put->data[(kiss_size - 1 - i) * put->dim[0].stride]),
+               sizeof(GFC_UINTEGER_4));
+
+      /* We put it after scrambling the bytes, to paper around users who
+        provide low-quality seeds.  */
+      scramble_seed ((unsigned char *) kiss_seed, seed, 4*kiss_size);
     }

   /* Return the seed to GET data.  */
@@ -689,9 +718,14 @@ random_seed (GFC_INTEGER_4 *size, gfc_ar
       if (((get->dim[0].ubound + 1 - get->dim[0].lbound)) < kiss_size)
        runtime_error ("Array size of GET is too small.");

+      /* Unscramble the seed.  */
+      unscramble_seed (seed, (unsigned char *) kiss_seed, 4*kiss_size);
+
       /*  This code now should do correct strides.  */
       for (i = 0; i < kiss_size; i++)
-        get->data[i * get->dim[0].stride] = (GFC_INTEGER_4) kiss_seed[i];
+       memcpy (&(get->data[(kiss_size - 1 - i) * get->dim[0].stride]),
+               seed + i * sizeof(GFC_UINTEGER_4),
+               sizeof(GFC_UINTEGER_4));
     }

   __gthread_mutex_unlock (&random_lock);


This doesn't make miracles (i.e. provide you with a good seed when you input a
particularly poor one), but at least it makes using the VALUES of DATE_AND_TIME
less frustrating (by generating visibly different streams of PRN).


-- 

fxcoudert at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |patch


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32812


  parent reply	other threads:[~2007-08-10 19:04 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-07-18 21:30 [Bug libfortran/32812] New: " tkoenig at gcc dot gnu dot org
2007-07-28 13:07 ` [Bug libfortran/32812] " fxcoudert at gcc dot gnu dot org
2007-08-10 19:04 ` fxcoudert at gcc dot gnu dot org [this message]
2007-08-10 19:10 ` kargl at gcc dot gnu dot org
2007-08-10 19:24 ` fxcoudert at gcc dot gnu dot org
2007-08-10 20:48 ` kargl at gcc dot gnu dot org
2007-08-10 21:28 ` fxcoudert at gcc dot gnu dot org
2007-08-12 11:19 ` tkoenig at gcc dot gnu dot org
2007-08-12 19:50 ` fxcoudert at gcc dot gnu dot org
2008-02-25 12:05 ` fxcoudert at gcc dot gnu dot org
2008-03-11 10:50 ` fxcoudert at gcc dot gnu dot org
2008-03-11 10:51 ` fxcoudert at gcc dot gnu dot org

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20070810190427.12413.qmail@sourceware.org \
    --to=gcc-bugzilla@gcc.gnu.org \
    --cc=gcc-bugs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).