diff -r 1ccc1ace9e5b runtime/doc/eval.txt
--- a/runtime/doc/eval.txt	Wed Nov 03 22:32:24 2010 +0100
+++ b/runtime/doc/eval.txt	Wed Nov 10 00:19:55 2010 +0800
@@ -1860,6 +1860,8 @@
 prevnonblank( {lnum})		Number	line nr of non-blank line <= {lnum}
 printf( {fmt}, {expr1}...)	String	format text
 pumvisible()			Number	whether popup menu is visible
+rand( {num1} [, {num2}])        Number  generate pseudo-random number
+randfloat( {num1} [, {num2}])	Float	generate pseudo-random float number
 range( {expr} [, {max} [, {stride}]])
 				List	items from {expr} to {max}
 readfile( {fname} [, {binary} [, {max}]])
@@ -1921,6 +1923,7 @@
 split( {expr} [, {pat} [, {keepempty}]])
 				List	make |List| from {pat} separated {expr}
 sqrt( {expr}			Float	squar root of {expr}
+srand( {seed})			none	set seed for random number generators
 str2float( {expr})		Float	convert String to Float
 str2nr( {expr} [, {base}])	Number	convert String to Number
 strchars( {expr})		Number	character length of the String {expr}
@@ -4538,6 +4541,29 @@
 		This can be used to avoid some things that would remove the
 		popup menu.
 
+rand({num1} [, {num2}])                                 *rand()*
+                Returns a pseudo-random number:
+		- If only {num1} is specified and {num1} >= 0: a random number
+		  N such that 0 <= N <= {num1}
+		- If only {num1} is specified and {num1} < 0: a random number
+		  N such that {num1} <= N <= 0
+		- If both {num1} and {num2} are specified and {num1} <= {num2}:
+		  a random number N such that {num1} <= N <= {num2}
+		- If both {num1} and {num2} are specified and {num1} > {num2}:
+		  a random number N such that {num2} <= N <= {num1}
+
+randfloat({num1} [, {num2}])				*randfloat()*
+		Returns a pseudo-random float number:
+		- If only {num1} is specified and {num1} >= 0: a random float
+		  number N such that 0 <= N <= {num1}
+		- If only {num1} is specified and {num1} < 0: a random float
+		  number N such that {num1} <= N <= 0
+		- If both {num1} and {num2} are specified and 
+		  {num1} <= {num2}: a random float number N such that 
+		  {num1} <= N <= {num2}
+		- If both {num1} and {num2} are specified and {num1} > {num2}:
+		  a random float number N such that {num2} <= N <= {num1}
+
 							*E726* *E727*
 range({expr} [, {max} [, {stride}]])				*range()*
 		Returns a |List| with Numbers:
@@ -5383,7 +5409,12 @@
 <			nan
 		"nan" may be different, it depends on system libraries.
 		{only available when compiled with the |+float| feature}
-		
+
+
+srand({seed})							*srand()*
+		Uses {seed} as a seed for a new sequence of pseudo-random
+		numbers to be returned by |rand()| and|randfloat()|.
+
 
 str2float( {expr})					*str2float()*
 		Convert String {expr} to a Float.  This mostly works the same
diff -r 1ccc1ace9e5b runtime/doc/tags
--- a/runtime/doc/tags	Wed Nov 03 22:32:24 2010 +0100
+++ b/runtime/doc/tags	Wed Nov 10 00:19:55 2010 +0800
@@ -7185,6 +7185,8 @@
 quotestar	gui.txt	/*quotestar*
 quote~	change.txt	/*quote~*
 r	change.txt	/*r*
+rand()	eval.txt	/*rand()*
+randfloat()	eval.txt	/*randfloat()*
 range()	eval.txt	/*range()*
 raw-terminal-mode	term.txt	/*raw-terminal-mode*
 rcp	pi_netrw.txt	/*rcp*
@@ -7545,6 +7547,7 @@
 sqlserver	ft_sql.txt	/*sqlserver*
 sqlsettype	ft_sql.txt	/*sqlsettype*
 sqrt()	eval.txt	/*sqrt()*
+srand()	eval.txt	/*srand()*
 sscanf	eval.txt	/*sscanf*
 standard-plugin	usr_05.txt	/*standard-plugin*
 standard-plugin-list	help.txt	/*standard-plugin-list*
diff -r 1ccc1ace9e5b runtime/doc/usr_41.txt
--- a/runtime/doc/usr_41.txt	Wed Nov 03 22:32:24 2010 +0100
+++ b/runtime/doc/usr_41.txt	Wed Nov 10 00:19:55 2010 +0800
@@ -874,6 +874,10 @@
 
 	mzeval()		evaluate |MzScheme| expression
 
+        rand()			generate a pseudo-random number
+	randfloat()		generate a pseudo-random float number
+	srand()			set seed for random number generators
+
 ==============================================================================
 *41.7*	Defining a function
 
diff -r 1ccc1ace9e5b src/eval.c
--- a/src/eval.c	Wed Nov 03 22:32:24 2010 +0100
+++ b/src/eval.c	Wed Nov 10 00:19:55 2010 +0800
@@ -654,6 +654,10 @@
 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));
+#ifdef FEAT_FLOAT
+static void f_randfloat __ARGS((typval_T *argvars, typval_T *rettv));
+#endif
 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));
@@ -702,6 +706,9 @@
 static void f_split __ARGS((typval_T *argvars, typval_T *rettv));
 #ifdef FEAT_FLOAT
 static void f_sqrt __ARGS((typval_T *argvars, typval_T *rettv));
+#endif
+static void f_srand __ARGS((typval_T *argvars, typval_T *rettv));
+#ifdef FEAT_FLOAT
 static void f_str2float __ARGS((typval_T *argvars, typval_T *rettv));
 #endif
 static void f_str2nr __ARGS((typval_T *argvars, typval_T *rettv));
@@ -833,7 +840,6 @@
 static int search_cmn __ARGS((typval_T *argvars, pos_T *match_pos, int *flagsp));
 static void setwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off));
 
-
 #ifdef EBCDIC
 static int compare_func_name __ARGS((const void *s1, const void *s2));
 static void sortFunctions __ARGS(());
@@ -7831,6 +7837,10 @@
     {"prevnonblank",	1, 1, f_prevnonblank},
     {"printf",		2, 19, f_printf},
     {"pumvisible",	0, 0, f_pumvisible},
+    {"rand",            1, 2, f_rand},
+#ifdef FEAT_FLOAT
+    {"randfloat",       1, 2, f_randfloat},
+#endif
     {"range",		1, 3, f_range},
     {"readfile",	1, 3, f_readfile},
     {"reltime",		0, 2, f_reltime},
@@ -7879,6 +7889,9 @@
     {"split",		1, 3, f_split},
 #ifdef FEAT_FLOAT
     {"sqrt",		1, 1, f_sqrt},
+#endif
+    {"srand",		1, 1, f_srand},
+#ifdef FEAT_FLOAT
     {"str2float",	1, 1, f_str2float},
 #endif
     {"str2nr",		1, 2, f_str2nr},
@@ -14149,6 +14162,131 @@
 }
 
 /*
+ * "rand()" function
+ */
+    static void
+f_rand(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    int		low;
+    int		high;
+    double	random_0_1;
+
+    /* make sure that the type of argvars[0] and argvars[1] must be number */
+    if (argvars[0].v_type != VAR_NUMBER)
+    {
+	EMSG(_("The first parameter must be a number."));
+	return;
+    }
+
+    if (argvars[1].v_type != VAR_NUMBER && argvars[1].v_type != VAR_UNKNOWN)
+    {
+	EMSG(_("The second parameter must be a number."));
+	return;
+    }
+
+    /* 
+     * if only one parameter is provided, then set low to zero and high to the
+     * first parameter. else set low to the first parameter and high to the
+     * second parameter.
+     */
+    if (argvars[1].v_type == VAR_UNKNOWN)  
+    {
+	low = 0;
+	high = argvars[0].vval.v_number;
+    }
+    else
+    {
+	low = argvars[0].vval.v_number;
+	high = argvars[1].vval.v_number;
+    }
+
+    /* if low > high, then swap them */
+    if(low > high)
+    {
+	int tmp = low;
+	low = high;
+	high = tmp;
+    }
+
+    /* now generate the random number */
+    random_0_1 = rand()/(RAND_MAX+1.);
+    rettv->vval.v_number = low + (int)((high + 1 - low) * random_0_1);
+    rettv->v_type = VAR_NUMBER;
+}
+
+#ifdef FEAT_FLOAT
+
+/*
+ * "randfloat()" function
+ */
+    static void
+f_randfloat(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    double	low;
+    double	high;
+    double	random_0_1;
+
+    /* the type of argvars[0] and argvars[1] must be number or float */
+    if (argvars[0].v_type != VAR_NUMBER && argvars[0].v_type != VAR_FLOAT)
+    {
+        EMSG(_("The first parameter must be a number or a float."));
+        return;
+    }
+
+    if (argvars[1].v_type != VAR_NUMBER && argvars[1].v_type != VAR_FLOAT &&
+            argvars[1].v_type != VAR_UNKNOWN)
+    {
+        EMSG(_("The second parameter must be a number or a float."));
+        return;
+    }
+
+    /* 
+     * if only one parameter is provided, then set low to zero and high to the
+     * first parameter. else set low to the first parameter and high to the
+     * second parameter.
+     */
+    if (argvars[1].v_type == VAR_UNKNOWN)  
+    {
+	low = 0;
+	if (argvars[0].v_type == VAR_NUMBER)
+	    high = argvars[0].vval.v_number;
+	else
+	    high = argvars[0].vval.v_float;
+    }
+    else
+    {
+	if (argvars[0].v_type == VAR_NUMBER)
+	    low = argvars[0].vval.v_number;
+	else
+	    low = argvars[0].vval.v_float;
+
+	if (argvars[1].v_type == VAR_NUMBER)
+	    high = argvars[1].vval.v_number;
+	else
+	    high = argvars[1].vval.v_float;
+    }
+
+    /* if low > high, then swap them */
+    if(low > high)
+    {
+        double tmp = low;
+        low = high;
+        high = tmp;
+    }
+
+    /* now generate the random number */
+    random_0_1 = (double)rand()/RAND_MAX;
+    rettv->vval.v_float = low + (high- low) * random_0_1;
+    rettv->v_type = VAR_FLOAT;
+}
+
+#endif
+
+/*
  * "range()" function
  */
     static void
@@ -16668,7 +16806,35 @@
     else
 	rettv->vval.v_float = 0.0;
 }
-
+#endif
+
+/*
+ * "srand()" function
+ */
+    static void
+f_srand(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv UNUSED;
+{
+    long	seed;
+    int		error = FALSE;
+
+    seed = get_tv_number_chk(&argvars[0], &error);
+
+    if (error)
+	return;
+
+    /* seed must be bigger than zero */
+    if (seed <= 0)
+    {
+	EMSG("The seed must be bigger than zero.");
+	return;
+    }
+
+    srand(seed);
+}
+
+#ifdef FEAT_FLOAT
 /*
  * "str2float()" function
  */
