Hi Shlomi!

On Sa, 18 Sep 2010, Shlomi Fish wrote:

> 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 <[email protected]> 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.
> }}}

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

-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -4522,6 +4522,11 @@
 		This can be used to avoid some things that would remove the
 		popup menu.
 
+rand([{seed}])						*rand()*
+		Returns a pseudo-random positive integer Number between 0 and
+		65536. If {seed} is given, the random number generator will be
+		seeded with the given value.
+
 							*E726* *E727*
 range({expr} [, {max} [, {stride}]])				*range()*
 		Returns a |List| with Numbers:
diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt
--- a/runtime/doc/usr_41.txt
+++ b/runtime/doc/usr_41.txt
@@ -867,6 +867,7 @@
 
 	getreg()		get contents of a register
 	getregtype()		get type of a register
+	rand()			return a random number
 	setreg()		set contents and type of a register
 
 	taglist()		get list of matching tags
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, 1, f_rand},
     {"range",		1, 3, f_range},
     {"readfile",	1, 3, f_readfile},
     {"reltime",		0, 2, f_reltime},
@@ -14224,6 +14226,32 @@
 	rettv->vval.v_number = 1;
 #endif
 }
+/*
+ * "rand()" function
+ */
+    static void
+f_rand(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    static int init = FALSE;
+
+    if (!init && argvars[0].v_type == VAR_UNKNOWN)
+    {
+	srand((varnumber_T)time(NULL));
+	init = TRUE;
+    }
+    else if (argvars[0].v_type == VAR_NUMBER)
+    {
+	srand((varnumber_T)argvars[0].vval.v_number);
+	if (!init)
+	    init = TRUE;
+    }
+    rettv->v_type = VAR_NUMBER;
+
+    /* return a random number between 0 and 65k */
+    rettv->vval.v_number = (int) ((32767.0+1.0) * rand()/(RAND_MAX + 1.0));
+}
 
 /*
  * "range()" function

Raspunde prin e-mail lui