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.
}}}

However, see below:

> 
> 
> --- 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();
> +}

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 .

-- 
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

Raspunde prin e-mail lui