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	Mon Nov 08 15:00:39 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}]])
@@ -4538,6 +4540,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:
diff -r 1ccc1ace9e5b runtime/doc/tags
--- a/runtime/doc/tags	Wed Nov 03 22:32:24 2010 +0100
+++ b/runtime/doc/tags	Mon Nov 08 15:00:39 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*
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	Mon Nov 08 15:00:39 2010 +0800
@@ -874,6 +874,9 @@
 
 	mzeval()		evaluate |MzScheme| expression
 
+        rand()			generate a pseudo-random number
+	randfloat()		generate a pseudo-random float number
+
 ==============================================================================
 *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	Mon Nov 08 15:00:39 2010 +0800
@@ -18,6 +18,8 @@
 
 #if defined(FEAT_EVAL) || defined(PROTO)
 
+#include <time.h>       /* for time() */
+
 #ifdef AMIGA
 # include <time.h>	/* for strftime() */
 #endif
@@ -654,6 +656,8 @@
 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_randfloat __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));
@@ -833,6 +837,8 @@
 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));
 
+static int rand_int __ARGS((int low, int high));
+static double rand_double __ARGS((double low, double high));
 
 #ifdef EBCDIC
 static int compare_func_name __ARGS((const void *s1, const void *s2));
@@ -852,6 +858,8 @@
     int		    i;
     struct vimvar   *p;
 
+    srand(time(NULL));
+
     init_var_dict(&globvardict, &globvars_var);
     init_var_dict(&vimvardict, &vimvars_var);
     hash_init(&compat_hashtab);
@@ -7831,6 +7839,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},
@@ -14148,6 +14160,151 @@
 #endif
 }
 
+/* 
+ * generate a pseudo-random number between low and high
+ */
+    static int 
+rand_int(low, high)
+    int		low;
+    int		high;
+{
+    double	random_0_1;
+
+    random_0_1 = rand()/((double)RAND_MAX+1);
+    return low + (int) ((high + 1 - low) * random_0_1);
+}
+
+/* 
+ * generate a pseudo-random double float between low and high
+ */
+    static double
+rand_double(low, high)
+    double	low;
+    double	high;
+{
+    double	random_0_1;
+
+    random_0_1 = (double)rand()/RAND_MAX;
+    return low + (high- low) * random_0_1;
+}
+
+
+/*
+ * "rand()" function
+ */
+    static void
+f_rand(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    int		low;
+    int		high;
+
+    /* 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;
+    }
+
+
+    rettv->v_type = VAR_NUMBER;
+    rettv->vval.v_number = rand_int(low, high);
+}
+
+/*
+ * "randfloat()" function
+ */
+    static void
+f_randfloat(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    double	low;
+    double	high;
+
+    /* make sure that the type of argvars[0] and argvars[1] must be number */
+    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;
+    }
+
+    rettv->v_type = VAR_FLOAT;
+    rettv->vval.v_float = rand_double(low, high);
+}
+
 /*
  * "range()" function
  */
