Re: simple 16-bit random number generator

124 views
Skip to first unread message

Christian Brabandt

unread,
Sep 18, 2010, 8:49:29 AM9/18/10
to vim_use, vim...@googlegroups.com
Hi John!

On Fr, 17 Sep 2010, John Little wrote:

> On Sep 18, 3:05�am, Bee <200...@calcentral.com> wrote:
> function! Random()
> if !exists("s:seeded")
> call libcallnr("libc.so.6", "srand", localtime() )
> let s:seeded = 1
> endif
> return libcallnr("libc.so.6", "rand", 0 ) % 65536
> endfun
>
> You might have to adjust that "libc.so.6" for your OS.

This reminds me, that I have wished a rand() function for very long.

So here is a very simple patch. It doesn't add much to the footprint. I
am not sure, how portable the code is, though:


--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -4522,6 +4522,9 @@
This can be used to avoid some things that would remove the
popup menu.

+rand() *rand()*
+ Returns a pseudo-random positive integer Number.
+
*E726* *E727*
range({expr} [, {max} [, {stride}]]) *range()*
Returns a |List| with Numbers:
diff --git a/src/eval.c b/src/eval.c
--- a/src/eval.c
+++ b/src/eval.c
@@ -653,6 +653,7 @@
static void f_prevnonblank __ARGS((typval_T *argvars, typval_T *rettv));
static void f_printf __ARGS((typval_T *argvars, typval_T *rettv));
static void f_pumvisible __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_rand __ARGS((typval_T *argvars, typval_T *rettv));
static void f_range __ARGS((typval_T *argvars, typval_T *rettv));
static void f_readfile __ARGS((typval_T *argvars, typval_T *rettv));
static void f_reltime __ARGS((typval_T *argvars, typval_T *rettv));
@@ -7829,6 +7830,7 @@
{"prevnonblank", 1, 1, f_prevnonblank},
{"printf", 2, 19, f_printf},
{"pumvisible", 0, 0, f_pumvisible},
+ {"rand", 0, 0, f_rand},
{"range", 1, 3, f_range},
{"readfile", 1, 3, f_readfile},
{"reltime", 0, 2, f_reltime},
@@ -14224,6 +14226,18 @@
rettv->vval.v_number = 1;
#endif
}
+/*
+ * "rand()" function
+ */
+ static void
+f_rand(argvars, rettv)
+ typval_T *argvars;
+ typval_T *rettv;
+{
+ rettv->v_type = VAR_NUMBER;
+ srand((varnumber_T)time(NULL));
+ rettv->vval.v_number = rand();
+}


regards,
Christian

Shlomi Fish

unread,
Sep 18, 2010, 10:49:53 AM9/18/10
to vim...@googlegroups.com, Christian Brabandt, vim_use
Hi Christian,

On Saturday 18 September 2010 14:49:29 Christian Brabandt wrote:
> Hi John!
>
> On Fr, 17 Sep 2010, John Little wrote:
> > On Sep 18, 3:05 am, Bee <200...@calcentral.com> wrote:
> > function! Random()
> >
> > if !exists("s:seeded")
> >
> > call libcallnr("libc.so.6", "srand", localtime() )
> > let s:seeded = 1
> >
> > endif
> > return libcallnr("libc.so.6", "rand", 0 ) % 65536
> >
> > endfun
> >
> > You might have to adjust that "libc.so.6" for your OS.
>
> This reminds me, that I have wished a rand() function for very long.
>
> So here is a very simple patch. It doesn't add much to the footprint. I
> am not sure, how portable the code is, though:

According to man rand on Linux:

{{{
The functions rand() and srand() conform to SVr4, 4.3BSD, C89, C99,
POSIX.1-2001. The function rand_r() is from POSIX.1-2001.
POSIX.1-2008 marks rand_r() as obsolete.
}}}

And man time:

{{{
CONFORMING TO
SVr4, 4.3BSD, C89, C99, POSIX.1-2001. POSIX does not specify any error
conditions.
}}}

However, see below:

This is wrong. You're calling srand with the current time on every invocation
which will:

1. Yield non-predictable and non-reproducible results.

2. If two calls are done one right after the other within the same wall-clock
second, it will yield the exact same value.

A better idea would be to provide a binding for srand as well, so the user can
set a seed and get predictable results. An even better idea may be to provide
a consistent pseudo-random-number generator which will yield the same results
on all platforms. See:

http://www.haifux.org/lectures/79/

Regards,

Shlomi Fish

--
-----------------------------------------------------------------
Shlomi Fish http://www.shlomifish.org/
http://www.shlomifish.org/humour/ways_to_do_it.html

<rindolf> She's a hot chick. But she smokes.
<go|dfish> She can smoke as long as she's smokin'.

Please reply to list if it's a mailing list post - http://shlom.in/reply .

Christian Brabandt

unread,
Sep 19, 2010, 8:32:13 AM9/19/10
to vim...@googlegroups.com, vim_use
Hi Shlomi!

I know. But I don't know, whether this applies to all Windows versions.

>
> However, see below:
>
[...]


>
> This is wrong. You're calling srand with the current time on every invocation
> which will:
>
> 1. Yield non-predictable and non-reproducible results.
>
> 2. If two calls are done one right after the other within the same wall-clock
> second, it will yield the exact same value.

True. I thought, this would be good enough[™] for an editor.

Well, attached is an updated patch, that allows you to seed the random
generator and returns values between 0 and 32767

> A better idea would be to provide a binding for srand as well, so the
> user can set a seed and get predictable results. An even better idea
> may be to provide a consistent pseudo-random-number generator which
> will yield the same results on all platforms. See:
>
> http://www.haifux.org/lectures/79/

I don't know much about windows and looking at the slides, portability
seems to be a serious problem.

regards,
Christian

rand.patch
Reply all
Reply to author
Forward
0 new messages