On Wed, Apr 09, at 04:15 Charles E Campbell Jr wrote:
> 
> Bram Moolenaar wrote:
> >
> > OK, so we do need to worry about this.
> >
> > This patch to message.c, replacing the previous one, should do it.
> >   
> Hello!
> 
> I applied the first patch, and it worked.  However, the second one...
> 
> vim71/ djinni? patch -p0 < ../diff_float2.ptch
> patching file src/message.c
> Hunk #2 FAILED at 3823.
> Hunk #3 succeeded at 3819 with fuzz 2 (offset -53 lines).
> Hunk #4 succeeded at 4000 with fuzz 2 (offset 84 lines).
> Hunk #5 succeeded at 3965 (offset -53 lines).
> Hunk #6 FAILED at 4113.
> Hunk #7 succeeded at 4618 with fuzz 2 (offset 116 lines).
> Hunk #8 FAILED at 4772.
> 3 out of 8 hunks FAILED -- saving rejects to file src/message.c.rej
> 

Please try the attached patch on top of patch level 292.
Apply with -p1.


echo len(printf('%.350f', &100 / 3))
341

By the way, Thanks Bram!

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

diff -Naur vim71.orig/runtime/doc/eval.txt vim71/runtime/doc/eval.txt
--- vim71.orig/runtime/doc/eval.txt     2008-04-10 21:44:22.122448331 +0300
+++ vim71/runtime/doc/eval.txt  2008-04-10 21:40:51.361980814 +0300
@@ -39,11 +39,15 @@
                                                        *E712*
 There are five types of variables:
 
-Number         A 32 bit signed number.
+Number         A 32 bit signed number.  |expr-number|
                Examples:  -123  0x10  0177
 
+Float           A floating point number. |floating-point-format|
+               {only when compiled with the |+float| feature}
+               Examples: 123.456  1.15e-6  -1.1e3
+
 String         A NUL terminated string of 8-bit unsigned characters (bytes).
-               Examples: "ab\txx\"--"  'x-z''a,c'
+               |expr-string| Examples: "ab\txx\"--"  'x-z''a,c'
 
 Funcref                A reference to a function |Funcref|.
                Example: function("strlen")
@@ -92,6 +96,10 @@
 <                              *E745* *E728* *E703* *E729* *E730* *E731*
 List, Dictionary and Funcref types are not automatically converted.
 
+                                                       *E805* *E806*
+When mixing Number and Float the Number is converted to Float.  Otherwise
+there is no automatic conversion of Float.
+
                                                                *E706*
 You will get an error if you try to change the type of a variable.  You need
 to |:unlet| it first to avoid this error.  String and Number are considered
@@ -258,13 +266,13 @@
 <      0
 
 Thus comparing Lists is more strict than comparing numbers and strings.  You
-can compare simple values this way too by putting them in a string: >
+can compare simple values this way too by putting them in a list: >
 
        :let a = 5
        :let b = "5"
-       echo a == b
+       :echo a == b
 <      1 >
-       echo [a] == [b]
+       :echo [a] == [b]
 <      0
 
 
@@ -797,6 +805,8 @@
 
 None of these work for |Funcref|s.
 
+. and % do not work for Float. *E804*
+
 
 expr7                                                  *expr7*
 -----
@@ -909,6 +919,27 @@
 
 Decimal, Hexadecimal (starting with 0x or 0X), or Octal (starting with 0).
 
+                                               *floating-point-format*
+Floating point numbers can be written in two forms:
+- &N.M, where N and M are numbers.  The .M can be omitted.  The N cannot be
+  omitted.  There can be a minus sign in the N.  Examples:
+       &123.456
+       &0.0001
+       &55
+       &-0.123
+  Only a decimal point is accepted, not a comma.  No matter what the current
+  locale is.
+- Same, with a following exponent in the form "eX", where X is a decimal
+  number with an optional minus sign.  The 'e' can also be upper case.
+  Examples:
+       &1.234e3
+       &1E-6
+       &-3.1416e88
+The precision and range of floating points numbers depends on the library Vim
+was compiled with.  There is no way to change this at runtime.
+{only when compiled with the |+float| feature}
+
+
 
 string                                                 *expr-string* *E114*
 ------
@@ -2024,7 +2055,7 @@
 <              The current 'encoding' is used.  Example for "utf-8": >
                        char2nr("�")            returns 225
                        char2nr("�"[0])         returns 195
-<              nr2char() does the opposite.
+<              |nr2char()| does the opposite.
 
 cindent({lnum})                                                *cindent()*
                Get the amount of indent for line {lnum} according the C
@@ -3893,6 +3924,9 @@
                  %04x  hex number padded with zeros to at least 4 characters
                  %X    hex number using upper case letters
                  %o    octal number
+                 %f    floating point number in the form 123.456
+                 %e    floating point number in the form 1.234e3
+                 %E    floating pointer number in the form 1.234E3
                  %%    the % character itself
 
                Conversion specifications start with '%' and end with the
@@ -3951,6 +3985,8 @@
                        This gives the minimum number of digits to appear for
                        d, o, x, and X conversions, or the maximum number of
                        bytes to be printed from a string for s conversions.
+                       For floating point it is the number of digits after
+                       the decimal point.
 
                type
                        A character that specifies the type of conversion to
@@ -3968,6 +4004,7 @@
 
                The conversion specifiers and their meanings are:
 
+                               *printf-d* *printf-o* *printf-x* *printf-X*
                doxX    The Number argument is converted to signed decimal
                        (d), unsigned octal (o), or unsigned hexadecimal (x
                        and X) notation.  The letters "abcdef" are used for
@@ -3982,13 +4019,30 @@
                        a conversion is wider than the field width, the field
                        is expanded to contain the conversion result.
 
+                                                       *printf-c*
                c       The Number argument is converted to a byte, and the
                        resulting character is written.
 
+                                                       *printf-s*
                s       The text of the String argument is used.  If a
                        precision is specified, no more bytes than the number
                        specified are used.
 
+                                                       *printf-f* *E807*
+               f       The Float argument is converted into a string of the 
+                       form 123.456.  Currently doesn't do any padding.  The
+                       precision specifies the number of digits after the
+                       decimal point.  When the precision is zero the decimal
+                       point is omitted.  When the precision is not specified
+                       6 is used.
+
+                                                       *printf-e* *printf-E*
+                e E     The Float argument is converted into a string of the
+                       form 1.234e3 or 1.234E3 (when using 'E').  The
+                       precision specifies the number of digits after the
+                       decimal point, like with 'f'.
+
+                                                       *printf-%*
                %       A '%' is written.  No argument is converted.  The
                        complete conversion specification is "%%".
 
@@ -4781,6 +4835,19 @@
                Text after the number is silently ignored.
 
 
+str2float( {expr})                                     *str2float()*
+               Convert string {expr} to a Float.  This works the same as when
+               using a floating point number directly, see
+               |floating-point-format|, but without the leading '&'.
+               A comma is also accepted for a decimal point.
+               Text after the number is silently ignored.
+               A second comma or decimal point also ends the number:
+               "12,345.67" is converted to 12.345.  You can strip out
+               thousands separators with |substitute()|: >
+                       let f = str2float(substitute(text, ',', '', 'g'))
+<              {only when compiled with the |+float| feature}
+
+
 strftime({format} [, {time}])                          *strftime()*
                The result is a String, which is a formatted date and time, as
                specified by the {format} string.  The given {time} is used,
@@ -5142,6 +5209,7 @@
                        Funcref:    2
                        List:       3
                        Dictionary: 4
+                       Float:      5
                To avoid the magic numbers it should be used this way: >
                        :if type(myvar) == type(0)
                        :if type(myvar) == type("")
@@ -5200,6 +5268,8 @@
 <              This enters the same Visual mode as before.  It is also useful
                in scripts if you wish to act differently depending on the
                Visual mode that was used.
+               If Visual mode is active, use |mode()| to get the Visual mode
+               (e.g., in a |:vmap|).
 
                If an expression is supplied that results in a non-zero number
                or a non-empty string, then the Visual mode will be cleared
diff -Naur vim71.orig/src/auto/configure vim71/src/auto/configure
--- vim71.orig/src/auto/configure       2008-04-10 21:44:22.135444043 +0300
+++ vim71/src/auto/configure    2008-04-10 21:40:51.366978946 +0300
@@ -10311,9 +10311,10 @@
 
 
 
+
 for ac_header in stdarg.h stdlib.h string.h sys/select.h sys/utsname.h \
        termcap.h fcntl.h sgtty.h sys/ioctl.h sys/time.h sys/types.h termio.h \
-       iconv.h langinfo.h unistd.h stropts.h errno.h \
+       iconv.h langinfo.h math.h unistd.h stropts.h errno.h \
        sys/resource.h sys/systeminfo.h locale.h \
        sys/stream.h sys/ptem.h termios.h libc.h sys/statfs.h \
        poll.h sys/poll.h pwd.h utime.h sys/param.h libintl.h \
@@ -13083,6 +13084,138 @@
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
 
+
+echo "$as_me:$LINENO: checking for pow in -lm" >&5
+echo $ECHO_N "checking for pow in -lm... $ECHO_C" >&6
+if test "${ac_cv_lib_m_pow+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char pow ();
+int
+main ()
+{
+pow ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_m_pow=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_m_pow=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_m_pow" >&5
+echo "${ECHO_T}$ac_cv_lib_m_pow" >&6
+if test $ac_cv_lib_m_pow = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBM 1
+_ACEOF
+
+  LIBS="-lm $LIBS"
+
+fi
+
+echo "$as_me:$LINENO: checking for pow()" >&5
+echo $ECHO_N "checking for pow()... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#ifdef HAVE_MATH_H
+# include <math.h>
+#endif
+
+int
+main ()
+{
+double f = pow(1.1, 3.0);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; cat >>confdefs.h <<\_ACEOF
+#define HAVE_POW 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+
 echo "$as_me:$LINENO: checking --disable-acl argument" >&5
 echo $ECHO_N "checking --disable-acl argument... $ECHO_C" >&6
 # Check whether --enable-acl or --disable-acl was given.
diff -Naur vim71.orig/src/config.h.in vim71/src/config.h.in
--- vim71.orig/src/config.h.in  2007-04-26 17:40:34.000000000 +0300
+++ vim71/src/config.h.in       2008-04-10 21:40:51.367978692 +0300
@@ -150,6 +150,7 @@
 #undef HAVE_MEMSET
 #undef HAVE_NANOSLEEP
 #undef HAVE_OPENDIR
+#undef HAVE_POW
 #undef HAVE_PUTENV
 #undef HAVE_QSORT
 #undef HAVE_READLINK
@@ -199,6 +200,7 @@
 #undef HAVE_LIBGEN_H
 #undef HAVE_LIBINTL_H
 #undef HAVE_LOCALE_H
+#undef HAVE_MATH_H
 #undef HAVE_NDIR_H
 #undef HAVE_POLL_H
 #undef HAVE_PTHREAD_NP_H
diff -Naur vim71.orig/src/configure.in vim71/src/configure.in
--- vim71.orig/src/configure.in 2008-04-10 21:44:22.151439060 +0300
+++ vim71/src/configure.in      2008-04-10 21:40:51.368978290 +0300
@@ -2034,7 +2034,7 @@
 
 AC_CHECK_HEADERS(stdarg.h stdlib.h string.h sys/select.h sys/utsname.h \
        termcap.h fcntl.h sgtty.h sys/ioctl.h sys/time.h sys/types.h termio.h \
-       iconv.h langinfo.h unistd.h stropts.h errno.h \
+       iconv.h langinfo.h math.h unistd.h stropts.h errno.h \
        sys/resource.h sys/systeminfo.h locale.h \
        sys/stream.h sys/ptem.h termios.h libc.h sys/statfs.h \
        poll.h sys/poll.h pwd.h utime.h sys/param.h libintl.h \
@@ -2490,6 +2490,17 @@
        AC_MSG_RESULT(yes); AC_DEFINE(HAVE_NL_LANGINFO_CODESET),
        AC_MSG_RESULT(no))
 
+dnl Need pow() for floating point support.
+AC_CHECK_LIB(m, pow)
+AC_MSG_CHECKING(for pow())
+AC_TRY_LINK([
+#ifdef HAVE_MATH_H
+# include <math.h>
+#endif
+], [double f = pow(1.1, 3.0);],
+       AC_MSG_RESULT(yes); AC_DEFINE(HAVE_POW),
+       AC_MSG_RESULT(no))
+
 dnl Link with -lposix1e for ACL stuff; if not found, try -lacl for SGI
 dnl when -lacl works, also try to use -lattr (required for Debian).
 AC_MSG_CHECKING(--disable-acl argument)
diff -Naur vim71.orig/src/eval.c vim71/src/eval.c
--- vim71.orig/src/eval.c       2008-04-10 21:44:22.174431146 +0300
+++ vim71/src/eval.c    2008-04-10 21:40:51.381974296 +0300
@@ -30,6 +30,10 @@
 
 #if defined(FEAT_EVAL) || defined(PROTO)
 
+#if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
+# include <math.h>
+#endif
+
 #define DICT_MAXNEST 100       /* maximum nesting of lists and dicts */
 
 /*
@@ -349,10 +353,11 @@
 };
 
 /* shorthand */
-#define vv_type        vv_di.di_tv.v_type
-#define vv_nr  vv_di.di_tv.vval.v_number
-#define vv_str vv_di.di_tv.vval.v_string
-#define vv_tv  vv_di.di_tv
+#define vv_type                vv_di.di_tv.v_type
+#define vv_nr          vv_di.di_tv.vval.v_number
+#define vv_float       vv_di.di_tv.vval.v_float
+#define vv_str         vv_di.di_tv.vval.v_string
+#define vv_tv          vv_di.di_tv
 
 /*
  * The v: variables are stored in dictionary "vimvardict".
@@ -450,6 +455,10 @@
 static char_u *echo_string __ARGS((typval_T *tv, char_u **tofree, char_u 
*numbuf, int copyID));
 static char_u *tv2string __ARGS((typval_T *tv, char_u **tofree, char_u 
*numbuf, int copyID));
 static char_u *string_quote __ARGS((char_u *str, int function));
+#ifdef FEAT_FLOAT
+static void get_float_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate));
+static int string2float __ARGS((char_u *text, float_T *value, int comma));
+#endif
 static int get_env_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate));
 static int find_internal_func __ARGS((char_u *name));
 static char_u *deref_func_name __ARGS((char_u *name, int *lenp));
@@ -637,6 +646,9 @@
 static void f_spellbadword __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_spellsuggest __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_split __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));
 #ifdef HAVE_STRFTIME
 static void f_strftime __ARGS((typval_T *argvars, typval_T *rettv));
@@ -1421,7 +1433,8 @@
        || defined(FEAT_COMPL_FUNC) || defined(PROTO)
 /*
  * Call some vimL function and return the result in "*rettv".
- * Uses argv[argc] for the function arguments.
+ * Uses argv[argc] for the function arguments.  Only Number and String
+ * arguments are currently supported.
  * Returns OK or FAIL.
  */
     static int
@@ -2848,16 +2861,36 @@
                {
                    /* nr += nr  or  nr -= nr*/
                    n = get_tv_number(tv1);
-                   if (*op == '+')
-                       n += get_tv_number(tv2);
+#ifdef FEAT_FLOAT
+                   if (tv2->v_type == VAR_FLOAT)
+                   {
+                       float_T f = n;
+
+                       if (*op == '+')
+                           f += tv2->vval.v_float;
+                       else
+                           f -= tv2->vval.v_float;
+                       clear_tv(tv1);
+                       tv1->v_type = VAR_FLOAT;
+                       tv1->vval.v_float = f;
+                   }
                    else
-                       n -= get_tv_number(tv2);
-                   clear_tv(tv1);
-                   tv1->v_type = VAR_NUMBER;
-                   tv1->vval.v_number = n;
+#endif
+                   {
+                       if (*op == '+')
+                           n += get_tv_number(tv2);
+                       else
+                           n -= get_tv_number(tv2);
+                       clear_tv(tv1);
+                       tv1->v_type = VAR_NUMBER;
+                       tv1->vval.v_number = n;
+                   }
                }
                else
                {
+                   if (tv2->v_type == VAR_FLOAT)
+                       break;
+
                    /* str .= str */
                    s = get_tv_string(tv1);
                    s = concat_str(s, get_tv_string_buf(tv2, numbuf));
@@ -2866,6 +2899,27 @@
                    tv1->vval.v_string = s;
                }
                return OK;
+
+#ifdef FEAT_FLOAT
+           case VAR_FLOAT:
+               {
+                   float_T f;
+
+                   if (*op == '.' || (tv2->v_type != VAR_FLOAT
+                                   && tv2->v_type != VAR_NUMBER
+                                   && tv2->v_type != VAR_STRING))
+                       break;
+                   if (tv2->v_type == VAR_FLOAT)
+                       f = tv2->vval.v_float;
+                   else
+                       f = get_tv_number(tv2);
+                   if (*op == '+')
+                       tv1->vval.v_float += f;
+                   else
+                       tv1->vval.v_float -= f;
+               }
+               return OK;
+#endif
        }
     }
 
@@ -4237,6 +4291,40 @@
                }
            }
 
+#ifdef FEAT_FLOAT
+           /*
+            * If one of the two variables is a float, compare as a float.
+            * When using "=~" or "!~", always compare as string.
+            */
+           else if ((rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT)
+                   && type != TYPE_MATCH && type != TYPE_NOMATCH)
+           {
+               float_T f1, f2;
+
+               if (rettv->v_type == VAR_FLOAT)
+                   f1 = rettv->vval.v_float;
+               else
+                   f1 = get_tv_number(rettv);
+               if (var2.v_type == VAR_FLOAT)
+                   f2 = var2.vval.v_float;
+               else
+                   f2 = get_tv_number(&var2);
+               n1 = FALSE;
+               switch (type)
+               {
+                   case TYPE_EQUAL:    n1 = (f1 == f2); break;
+                   case TYPE_NEQUAL:   n1 = (f1 != f2); break;
+                   case TYPE_GREATER:  n1 = (f1 > f2); break;
+                   case TYPE_GEQUAL:   n1 = (f1 >= f2); break;
+                   case TYPE_SMALLER:  n1 = (f1 < f2); break;
+                   case TYPE_SEQUAL:   n1 = (f1 <= f2); break;
+                   case TYPE_UNKNOWN:
+                   case TYPE_MATCH:
+                   case TYPE_NOMATCH:  break;  /* avoid gcc warning */
+               }
+           }
+#endif
+
            /*
             * If one of the two variables is a number, compare as a number.
             * When using "=~" or "!~", always compare as string.
@@ -4329,6 +4417,9 @@
     typval_T   var3;
     int                op;
     long       n1, n2;
+#ifdef FEAT_FLOAT
+    float_T    f1 = 0, f2 = 0;
+#endif
     char_u     *s1, *s2;
     char_u     buf1[NUMBUFLEN], buf2[NUMBUFLEN];
     char_u     *p;
@@ -4348,7 +4439,11 @@
        if (op != '+' && op != '-' && op != '.')
            break;
 
-       if (op != '+' || rettv->v_type != VAR_LIST)
+       if ((op != '+' || rettv->v_type != VAR_LIST)
+#ifdef FEAT_FLOAT
+               && (op == '.' || rettv->v_type != VAR_FLOAT)
+#endif
+               )
        {
            /* For "list + ...", an illegal use of the first operand as
             * a number cannot be determined before evaluating the 2nd
@@ -4412,29 +4507,73 @@
            {
                int         error = FALSE;
 
-               n1 = get_tv_number_chk(rettv, &error);
-               if (error)
+#ifdef FEAT_FLOAT
+               if (rettv->v_type == VAR_FLOAT)
                {
-                   /* This can only happen for "list + non-list".
-                    * For "non-list + ..." or "something - ...", we returned
-                    * before evaluating the 2nd operand. */
-                   clear_tv(rettv);
-                   return FAIL;
+                   f1 = rettv->vval.v_float;
+                   n1 = 0;
                }
-               n2 = get_tv_number_chk(&var2, &error);
-               if (error)
+               else
+#endif
                {
-                   clear_tv(rettv);
-                   clear_tv(&var2);
-                   return FAIL;
+                   n1 = get_tv_number_chk(rettv, &error);
+                   if (error)
+                   {
+                       /* This can only happen for "list + non-list".  For
+                        * "non-list + ..." or "something - ...", we returned
+                        * before evaluating the 2nd operand. */
+                       clear_tv(rettv);
+                       return FAIL;
+                   }
+#ifdef FEAT_FLOAT
+                   if (var2.v_type == VAR_FLOAT)
+                       f1 = n1;
+#endif
+               }
+#ifdef FEAT_FLOAT
+               if (var2.v_type == VAR_FLOAT)
+               {
+                   f2 = var2.vval.v_float;
+                   n2 = 0;
+               }
+               else
+#endif
+               {
+                   n2 = get_tv_number_chk(&var2, &error);
+                   if (error)
+                   {
+                       clear_tv(rettv);
+                       clear_tv(&var2);
+                       return FAIL;
+                   }
+#ifdef FEAT_FLOAT
+                   if (rettv->v_type == VAR_FLOAT)
+                       f2 = n2;
+#endif
                }
                clear_tv(rettv);
-               if (op == '+')
-                   n1 = n1 + n2;
+
+#ifdef FEAT_FLOAT
+               /* If there is a float on either side the result is a float. */
+               if (rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT)
+               {
+                   if (op == '+')
+                       f1 = f1 + f2;
+                   else
+                       f1 = f1 - f2;
+                   rettv->v_type = VAR_FLOAT;
+                   rettv->vval.v_float = f1;
+               }
                else
-                   n1 = n1 - n2;
-               rettv->v_type = VAR_NUMBER;
-               rettv->vval.v_number = n1;
+#endif
+               {
+                   if (op == '+')
+                       n1 = n1 + n2;
+                   else
+                       n1 = n1 - n2;
+                   rettv->v_type = VAR_NUMBER;
+                   rettv->vval.v_number = n1;
+               }
            }
            clear_tv(&var2);
        }
@@ -4462,6 +4601,10 @@
     typval_T   var2;
     int                op;
     long       n1, n2;
+#ifdef FEAT_FLOAT
+    int                use_float = FALSE;
+    float_T    f1 = 0, f2;
+#endif
     int                error = FALSE;
 
     /*
@@ -4481,7 +4624,16 @@
 
        if (evaluate)
        {
-           n1 = get_tv_number_chk(rettv, &error);
+#ifdef FEAT_FLOAT
+           if (rettv->v_type == VAR_FLOAT)
+           {
+               f1 = rettv->vval.v_float;
+               use_float = TRUE;
+               n1 = 0;
+           }
+           else
+#endif
+               n1 = get_tv_number_chk(rettv, &error);
            clear_tv(rettv);
            if (error)
                return FAIL;
@@ -4498,32 +4650,80 @@
 
        if (evaluate)
        {
-           n2 = get_tv_number_chk(&var2, &error);
-           clear_tv(&var2);
-           if (error)
-               return FAIL;
+#ifdef FEAT_FLOAT
+           if (var2.v_type == VAR_FLOAT)
+           {
+               if (!use_float)
+               {
+                   f1 = n1;
+                   use_float = TRUE;
+               }
+               f2 = var2.vval.v_float;
+               n2 = 0;
+           }
+           else
+#endif
+           {
+               n2 = get_tv_number_chk(&var2, &error);
+               clear_tv(&var2);
+               if (error)
+                   return FAIL;
+#ifdef FEAT_FLOAT
+               if (use_float)
+                   f2 = n2;
+#endif
+           }
 
            /*
             * Compute the result.
+            * When either side is a float the result is a float.
             */
-           if (op == '*')
-               n1 = n1 * n2;
-           else if (op == '/')
+#ifdef FEAT_FLOAT
+           if (use_float)
            {
-               if (n2 == 0)    /* give an error message? */
-                   n1 = 0x7fffffffL;
+               if (op == '*')
+                   f1 = f1 * f2;
+               else if (op == '/')
+               {
+                   if (f2 == 0.0)      /* give an error message? */
+# ifdef INFINITY
+                       f1 = INFINITY;
+# else
+                       f1 = 0x7fffffffL;
+# endif
+                   else
+                       f1 = f1 / f2;
+               }
                else
-                   n1 = n1 / n2;
+               {
+                   EMSG(_("E804: Cannot use % with float"));
+                   return FAIL;
+               }
+               rettv->v_type = VAR_FLOAT;
+               rettv->vval.v_float = f1;
            }
            else
+#endif
            {
-               if (n2 == 0)    /* give an error message? */
-                   n1 = 0;
+               if (op == '*')
+                   n1 = n1 * n2;
+               else if (op == '/')
+               {
+                   if (n2 == 0)        /* give an error message? */
+                       n1 = 0x7fffffffL;
+                   else
+                       n1 = n1 / n2;
+               }
                else
-                   n1 = n1 % n2;
+               {
+                   if (n2 == 0)        /* give an error message? */
+                       n1 = 0;
+                   else
+                       n1 = n1 % n2;
+               }
+               rettv->v_type = VAR_NUMBER;
+               rettv->vval.v_number = n1;
            }
-           rettv->v_type = VAR_NUMBER;
-           rettv->vval.v_number = n1;
        }
     }
 
@@ -4565,7 +4765,6 @@
     long       n;
     int                len;
     char_u     *s;
-    int                val;
     char_u     *start_leader, *end_leader;
     int                ret = OK;
     char_u     *alias;
@@ -4635,7 +4834,13 @@
     /*
      * Option value: &name
      */
-    case '&':  ret = get_option_tv(arg, rettv, evaluate);
+    case '&':
+#ifdef FEAT_FLOAT
+               if (vim_isdigit(*(*arg + 1)))
+                   get_float_tv(arg, rettv, evaluate);
+               else
+#endif
+                   ret = get_option_tv(arg, rettv, evaluate);
                break;
 
     /*
@@ -4734,8 +4939,15 @@
     if (ret == OK && evaluate && end_leader > start_leader)
     {
        int         error = FALSE;
+       int         val = 0;
+#ifdef FEAT_FLOAT
+       float_T     f = 0;
 
-       val = get_tv_number_chk(rettv, &error);
+       if (rettv->v_type == VAR_FLOAT)
+           f = rettv->vval.v_float;
+       else
+#endif
+           val = get_tv_number_chk(rettv, &error);
        if (error)
        {
            clear_tv(rettv);
@@ -4747,13 +4959,37 @@
            {
                --end_leader;
                if (*end_leader == '!')
-                   val = !val;
+               {
+#ifdef FEAT_FLOAT
+                   if (rettv->v_type == VAR_FLOAT)
+                       f = !f;
+                   else
+#endif
+                       val = !val;
+               }
                else if (*end_leader == '-')
-                   val = -val;
+               {
+#ifdef FEAT_FLOAT
+                   if (rettv->v_type == VAR_FLOAT)
+                       f = -f;
+                   else
+#endif
+                       val = -val;
+               }
+           }
+#ifdef FEAT_FLOAT
+           if (rettv->v_type == VAR_FLOAT)
+           {
+               clear_tv(rettv);
+               rettv->vval.v_float = f;
+           }
+           else
+#endif
+           {
+               clear_tv(rettv);
+               rettv->v_type = VAR_NUMBER;
+               rettv->vval.v_number = val;
            }
-           clear_tv(rettv);
-           rettv->v_type = VAR_NUMBER;
-           rettv->vval.v_number = val;
        }
     }
 
@@ -4780,7 +5016,11 @@
     char_u     *s;
     char_u     *key = NULL;
 
-    if (rettv->v_type == VAR_FUNC)
+    if (rettv->v_type == VAR_FUNC
+#ifdef FEAT_FLOAT
+           || rettv->v_type == VAR_FLOAT
+#endif
+           )
     {
        if (verbose)
            EMSG(_("E695: Cannot index a Funcref"));
@@ -5566,7 +5806,7 @@
 /*
  * Return TRUE if "tv1" and "tv2" have the same value.
  * Compares the items just like "==" would compare them, but strings and
- * numbers are different.
+ * numbers are different.  Floats and numbers are also different.
  */
     static int
 tv_equal(tv1, tv2, ic)
@@ -5608,6 +5848,11 @@
        case VAR_NUMBER:
            return tv1->vval.v_number == tv2->vval.v_number;
 
+#ifdef FEAT_FLOAT
+       case VAR_FLOAT:
+           return tv1->vval.v_float == tv2->vval.v_float;
+#endif
+
        case VAR_STRING:
            s1 = get_tv_string_buf(tv1, buf1);
            s2 = get_tv_string_buf(tv2, buf2);
@@ -6897,6 +7142,14 @@
            r = get_tv_string_buf(tv, numbuf);
            break;
 
+#ifdef FEAT_FLOAT
+       case VAR_FLOAT:
+           *tofree = NULL;
+           vim_snprintf(numbuf, NUMBUFLEN, "%f", tv->vval.v_float);
+           r = numbuf;
+           break;
+#endif
+
        default:
            EMSG2(_(e_intern2), "echo_string()");
            *tofree = NULL;
@@ -6929,6 +7182,9 @@
            *tofree = string_quote(tv->vval.v_string, FALSE);
            return *tofree;
        case VAR_NUMBER:
+#ifdef FEAT_FLOAT
+       case VAR_FLOAT:
+#endif
        case VAR_LIST:
        case VAR_DICT:
            break;
@@ -6984,6 +7240,71 @@
     return s;
 }
 
+#ifdef FEAT_FLOAT
+/*
+ * Get the value of a floating point number: &123.456
+ * "arg" is pointing to the '&'.  It is advanced to after the number.
+ */
+    static void
+get_float_tv(arg, rettv, evaluate)
+    char_u     **arg;
+    typval_T   *rettv;
+    int                evaluate;
+{
+    float_T    f;
+
+    ++*arg;
+    *arg += string2float(*arg, &f, FALSE);
+    if (evaluate)
+    {
+       rettv->v_type = VAR_FLOAT;
+       rettv->vval.v_float = f;
+    }
+}
+
+/*
+ * Convert the sting "text" to a floating point number.
+ * Returns the length of the text that was consumed.
+ */
+    static int
+string2float(text, value, comma)
+    char_u     *text;
+    float_T    *value;     /* result stored here */
+    int                comma;      /* accept a comma as decimal separator */
+{
+    char_u     *s = text;
+    int                len;
+    long       n;
+    float_T    f;
+
+    vim_str2nr(s, NULL, &len, FALSE, FALSE, &n, NULL);
+    s += len;
+    f = n;
+
+    if ((*s == '.' || (comma && *s == ',')) && s[1] != '-')
+    {
+       ++s;
+       vim_str2nr(s, NULL, &len, FALSE, FALSE, &n, NULL);
+       s += len;
+       f += (float_T)n / pow(10.0, (double)len);
+    }
+
+    /* 1.234e-20 */
+    if (*s == 'e' || *s == 'E')
+    {
+       ++s;
+       if (*s == '+')      /* accept 1.234e+3 */
+           ++s;
+       vim_str2nr(s, NULL, &len, FALSE, FALSE, &n, NULL);
+       s += len;
+       f *= pow(10.0, (double)n);
+    }
+
+    *value = f;
+    return (int)(s - text);
+}
+#endif
+
 /*
  * Get the value of an environment variable.
  * "arg" is pointing to the '$'.  It is advanced to after the name.
@@ -7240,6 +7561,9 @@
     {"spellbadword",   0, 1, f_spellbadword},
     {"spellsuggest",   1, 3, f_spellsuggest},
     {"split",          1, 3, f_split},
+#ifdef FEAT_FLOAT
+    {"str2float",      1, 1, f_str2float},
+#endif
     {"str2nr",         1, 2, f_str2nr},
 #ifdef HAVE_STRFTIME
     {"strftime",       1, 2, f_strftime},
@@ -8800,6 +9124,11 @@
        case VAR_NUMBER:
            n = argvars[0].vval.v_number == 0;
            break;
+#ifdef FEAT_FLOAT
+       case VAR_FLOAT:
+           n = argvars[0].vval.v_float == 0.0;
+           break;
+#endif
        case VAR_LIST:
            n = argvars[0].vval.v_list == NULL
                                  || argvars[0].vval.v_list->lv_first == NULL;
@@ -10877,6 +11206,9 @@
 #ifdef FEAT_FIND_ID
        "find_in_path",
 #endif
+#ifdef FEAT_FLOAT
+       "float",
+#endif
 #ifdef FEAT_FOLDING
        "folding",
 #endif
@@ -15432,6 +15764,21 @@
     p_cpo = save_cpo;
 }
 
+#ifdef FEAT_FLOAT
+/*
+ * "str2float()" function
+ */
+    static void
+f_str2float(argvars, rettv)
+    typval_T   *argvars;
+    typval_T   *rettv;
+{
+    (void)string2float(skipwhite(get_tv_string(&argvars[0])),
+                                                 &rettv->vval.v_float, TRUE);
+    rettv->v_type = VAR_FLOAT;
+}
+#endif
+
 /*
  * "str2nr()" function
  */
@@ -16476,6 +16823,9 @@
        case VAR_FUNC:   n = 2; break;
        case VAR_LIST:   n = 3; break;
        case VAR_DICT:   n = 4; break;
+#ifdef FEAT_FLOAT
+       case VAR_FLOAT:  n = 5; break;
+#endif
        default: EMSG2(_(e_intern2), "f_type()"); n = 0; break;
     }
     rettv->vval.v_number = n;
@@ -17662,6 +18012,9 @@
                dict_unref(varp->vval.v_dict);
                break;
            case VAR_NUMBER:
+#ifdef FEAT_FLOAT
+           case VAR_FLOAT:
+#endif
            case VAR_UNKNOWN:
                break;
            default:
@@ -17701,6 +18054,11 @@
            case VAR_NUMBER:
                varp->vval.v_number = 0;
                break;
+#ifdef FEAT_FLOAT
+           case VAR_FLOAT:
+               varp->vval.v_float = 0;
+               break;
+#endif
            case VAR_UNKNOWN:
                break;
            default:
@@ -17749,6 +18107,11 @@
     {
        case VAR_NUMBER:
            return (long)(varp->vval.v_number);
+#ifdef FEAT_FLOAT
+       case VAR_FLOAT:
+           EMSG(_("E805: Using a Float as a number"));
+           break;
+#endif
        case VAR_FUNC:
            EMSG(_("E703: Using a Funcref as a number"));
            break;
@@ -17872,6 +18235,11 @@
        case VAR_DICT:
            EMSG(_("E731: using Dictionary as a String"));
            break;
+#ifdef FEAT_FLOAT
+       case VAR_FLOAT:
+           EMSG(_("E806: using Float as a String"));
+           break;
+#endif
        case VAR_STRING:
            if (varp->vval.v_string != NULL)
                return varp->vval.v_string;
@@ -18410,6 +18778,11 @@
        case VAR_NUMBER:
            to->vval.v_number = from->vval.v_number;
            break;
+#ifdef FEAT_FLOAT
+       case VAR_FLOAT:
+           to->vval.v_float = from->vval.v_float;
+           break;
+#endif
        case VAR_STRING:
        case VAR_FUNC:
            if (from->vval.v_string == NULL)
@@ -18472,6 +18845,9 @@
     switch (from->v_type)
     {
        case VAR_NUMBER:
+#ifdef FEAT_FLOAT
+       case VAR_FLOAT:
+#endif
        case VAR_STRING:
        case VAR_FUNC:
            copy_tv(from, to);
@@ -20846,9 +21222,9 @@
 #if defined(FEAT_VIMINFO) || defined(FEAT_SESSION)
 typedef enum
 {
-    VAR_FLAVOUR_DEFAULT,
-    VAR_FLAVOUR_SESSION,
-    VAR_FLAVOUR_VIMINFO
+    VAR_FLAVOUR_DEFAULT,       /* doesn't start with uppercase */
+    VAR_FLAVOUR_SESSION,       /* starts with uppercase, some lower */
+    VAR_FLAVOUR_VIMINFO                /* all uppercase */
 } var_flavour_T;
 
 static var_flavour_T var_flavour __ARGS((char_u *varname));
@@ -20881,7 +21257,7 @@
     int                writing;
 {
     char_u     *tab;
-    int                is_string = FALSE;
+    int                type = VAR_NUMBER;
     typval_T   tv;
 
     if (!writing && (find_viminfo_parameter('!') != NULL))
@@ -20891,24 +21267,27 @@
        {
            *tab++ = '\0';      /* isolate the variable name */
            if (*tab == 'S')    /* string var */
-               is_string = TRUE;
+               type = VAR_STRING;
+#ifdef FEAT_FLOAT
+           else if (*tab == 'F')
+               type = VAR_FLOAT;
+#endif
 
            tab = vim_strchr(tab, '\t');
            if (tab != NULL)
            {
-               if (is_string)
-               {
-                   tv.v_type = VAR_STRING;
+               tv.v_type = type;
+               if (type == VAR_STRING)
                    tv.vval.v_string = viminfo_readstring(virp,
                                       (int)(tab - virp->vir_line + 1), TRUE);
-               }
+#ifdef FEAT_FLOAT
+               else if (type == VAR_FLOAT)
+                   (void)string2float(tab + 1, &tv.vval.v_float, TRUE);
+#endif
                else
-               {
-                   tv.v_type = VAR_NUMBER;
                    tv.vval.v_number = atol((char *)tab + 1);
-               }
                set_var(virp->vir_line + 1, &tv, FALSE);
-               if (is_string)
+               if (type == VAR_STRING)
                    vim_free(tv.vval.v_string);
            }
        }
@@ -20950,6 +21329,9 @@
                {
                    case VAR_STRING: s = "STR"; break;
                    case VAR_NUMBER: s = "NUM"; break;
+#ifdef FEAT_FLOAT
+                   case VAR_FLOAT: s = "FLO"; break;
+#endif
                    default: continue;
                }
                fprintf(fp, "!%s\t%s\t", this_var->di_key, s);
@@ -21009,6 +21391,24 @@
                }
                vim_free(p);
            }
+#ifdef FEAT_FLOAT
+           else if (this_var->di_tv.v_type == VAR_FLOAT
+                   && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION)
+           {
+               float_T f = this_var->di_tv.vval.v_float;
+               int sign = ' ';
+
+               if (f < 0)
+               {
+                   f = -f;
+                   sign = '-';
+               }
+               if ((fprintf(fd, "let %s = %c&%f",
+                                              this_var->di_key, sign, f) < 0)
+                       || put_eol(fd) == FAIL)
+                   return FAIL;
+           }
+#endif
        }
     }
     return OK;
@@ -21080,7 +21480,7 @@
        vim_free(*bufp);
        *fnamep = *bufp = newbuf;
 
-       l = GetShortPathName(*fnamep,*fnamep,l+1);
+       l = GetShortPathName(*fnamep, *fnamep, l+1);
 
        /* Really should always succeed, as the buffer is big enough */
     }
diff -Naur vim71.orig/src/feature.h vim71/src/feature.h
--- vim71.orig/src/feature.h    2008-04-10 21:44:22.195424329 +0300
+++ vim71/src/feature.h 2008-04-10 21:40:51.381974296 +0300
@@ -35,7 +35,7 @@
  * +small              few features enabled, as basic as possible
  * +normal             A default selection of features enabled
  * +big                        many features enabled, as rich as possible.
- * +huge               all possible featues enabled.
+ * +huge               all possible features enabled.
  *
  * When +small is used, +tiny is also included.  +normal implies +small, etc.
  */
@@ -376,9 +376,13 @@
 /*
  * +eval               Built-in script language and expression evaluation,
  *                     ":let", ":if", etc.
+ * +float              Floating point variables.
  */
 #ifdef FEAT_NORMAL
 # define FEAT_EVAL
+# if defined(HAVE_POW)
+#  define FEAT_FLOAT
+# endif
 #endif
 
 /*
diff -Naur vim71.orig/src/if_python.c vim71/src/if_python.c
--- vim71.orig/src/if_python.c  2007-03-07 00:00:53.000000000 +0200
+++ vim71/src/if_python.c       2008-04-10 21:40:51.382974351 +0300
@@ -1130,6 +1130,17 @@
        result = Py_BuildValue("s", buf);
        PyDict_SetItemString(lookupDict, ptrBuf, result);
     }
+#ifdef FEAT_FLOAT
+    else if (our_tv->v_type == VAR_FLOAT)
+    {
+       char buf[NUMBUFLEN];
+
+       /* For backwards compatibility numbers are stored as strings. */
+       sprintf(buf, "%f", (long)our_tv->vval.v_float);
+       result = Py_BuildValue("s", buf);
+       PyDict_SetItemString(lookupDict, ptrBuf, result);
+    }
+#endif
     else if (our_tv->v_type == VAR_LIST)
     {
        list_T          *list = our_tv->vval.v_list;
diff -Naur vim71.orig/src/message.c vim71/src/message.c
--- vim71.orig/src/message.c    2008-04-10 21:44:22.230412683 +0300
+++ vim71/src/message.c 2008-04-10 21:40:45.664888239 +0300
@@ -15,6 +15,10 @@
 
 #include "vim.h"
 
+#if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
+# include <math.h>
+#endif
+
 static int other_sourcing_name __ARGS((void));
 static char_u *get_emsg_source __ARGS((void));
 static char_u *get_emsg_lnum __ARGS((void));
@@ -3819,6 +3823,9 @@
 
 static long tv_nr __ARGS((typval_T *tvs, int *idxp));
 static char *tv_str __ARGS((typval_T *tvs, int *idxp));
+# ifdef FEAT_FLOAT
+static double tv_float __ARGS((typval_T *tvs, int *idxp));
+# endif
 
 /*
  * Get number argument from "idxp" entry in "tvs".  First entry is 1.
@@ -3865,6 +3872,32 @@
     }
     return s;
 }
+
+# ifdef FEAT_FLOAT
+/*
+ * Get float argument from "idxp" entry in "tvs".  First entry is 1.
+ */
+    static double
+tv_float(tvs, idxp)
+    typval_T   *tvs;
+    int                *idxp;
+{
+    int                idx = *idxp - 1;
+    double     f = 0;
+
+    if (tvs[idx].v_type == VAR_UNKNOWN)
+       EMSG(_(e_printf));
+    else
+    {
+       ++*idxp;
+       if (tvs[idx].v_type == VAR_FLOAT)
+           f = tvs[idx].vval.v_float;
+       else
+           EMSG(_("E807: Expected Float argument for printf()"));
+    }
+    return f;
+}
+# endif
 #endif
 
 /*
@@ -3883,6 +3916,8 @@
  * with flags: '-', '+', ' ', '0' and '#'.
  * An asterisk is supported for field width as well as precision.
  *
+ * Limited support for 'f', 'e' and 'E' (floating point) was added.
+ *
  * Length modifiers 'h' (short int) and 'l' (long int) are supported.
  * 'll' (long long int) is not supported.
  *
@@ -3983,7 +4018,14 @@
            char    length_modifier = '\0';
 
            /* temporary buffer for simple numeric->string conversion */
-           char    tmp[32];
+#ifdef FEAT_FLOAT
+# define TMP_LEN 350   /* On my system 1e308 is the biggest number possible.
+                        * That sounds reasonable to use as the maximum
+                        * printable. */
+#else
+# define TMP_LEN 32
+#endif
+           char    tmp[TMP_LEN];
 
            /* string address in case of string argument */
            char    *str_arg;
@@ -4124,6 +4166,7 @@
                case 'D': fmt_spec = 'd'; length_modifier = 'l'; break;
                case 'U': fmt_spec = 'u'; length_modifier = 'l'; break;
                case 'O': fmt_spec = 'o'; length_modifier = 'l'; break;
+               case 'F': fmt_spec = 'f'; break;
                default: break;
            }
 
@@ -4459,6 +4502,53 @@
                    break;
                }
 
+#ifdef FEAT_FLOAT
+           case 'f':
+           case 'e':
+           case 'E':
+               {
+                   /* Floating point.  Very limited at the moment. */
+                   double      f;
+                   char        format[40];
+                   int         l;
+
+                   f =
+# ifndef HAVE_STDARG_H
+                       get_a_arg(arg_idx);
+# else
+#  if defined(FEAT_EVAL)
+                       tvs != NULL ? tv_float(tvs, &arg_idx) :
+#  endif
+                           va_arg(ap, double);
+# endif
+                   if (fmt_spec == 'f' && f > 1.0e307)
+                   {
+                       /* Avoid a buffer overflow */
+                       strcpy(tmp, "inf");
+                       str_arg_l = 3;
+                   }
+                   else
+                   {
+                       format[0] = '%';
+                       l = 1;
+                       if (precision_specified)
+                       {
+                           if (fmt_spec == 'f'
+                                   && log10(f) + precision > TMP_LEN - 10)
+                               precision = TMP_LEN - 10 - log10(f);
+                           else if (precision > TMP_LEN - 10)
+                               precision = TMP_LEN - 10;
+                           l += sprintf(format + 1, ".%d", precision);
+                       }
+                       format[l] = fmt_spec;
+                       format[l + 1] = NUL;
+                       str_arg_l = sprintf(tmp, format, f);
+                   }
+                   str_arg = tmp;
+                   break;
+               }
+#endif
+
            default:
                /* unrecognized conversion specifier, keep format string
                 * as-is */
@@ -4566,7 +4656,8 @@
            if (justify_left)
            {
                /* right blank padding to the field width */
-               int pn = (int)(min_field_width - (str_arg_l + 
number_of_zeros_to_pad));
+               int pn = (int)(min_field_width
+                                     - (str_arg_l + number_of_zeros_to_pad));
 
                if (pn > 0)
                {
diff -Naur vim71.orig/src/structs.h vim71/src/structs.h
--- vim71.orig/src/structs.h    2008-04-10 21:44:22.288393601 +0300
+++ vim71/src/structs.h 2008-04-10 21:40:51.384973103 +0300
@@ -1005,6 +1005,7 @@
 #else
 typedef int    varnumber_T;
 #endif
+typedef double float_T;
 
 typedef struct listvar_S list_T;
 typedef struct dictvar_S dict_T;
@@ -1019,6 +1020,9 @@
     union
     {
        varnumber_T     v_number;       /* number value */
+#ifdef FEAT_FLOAT
+       float_T         v_float;        /* floating number value */
+#endif
        char_u          *v_string;      /* string value (can be NULL!) */
        list_T          *v_list;        /* list value (can be NULL!) */
        dict_T          *v_dict;        /* dict value (can be NULL!) */
@@ -1032,6 +1036,7 @@
 #define VAR_FUNC    3  /* "v_string" is function name */
 #define VAR_LIST    4  /* "v_list" is used */
 #define VAR_DICT    5  /* "v_dict" is used */
+#define VAR_FLOAT   6  /* "v_float" is used */
 
 /* Values for "v_lock". */
 #define VAR_LOCKED  1  /* locked with lock(), can use unlock() */
diff -Naur vim71.orig/src/version.c vim71/src/version.c
--- vim71.orig/src/version.c    2008-04-10 21:44:22.301389216 +0300
+++ vim71/src/version.c 2008-04-10 21:40:51.385973840 +0300
@@ -217,6 +217,11 @@
 #else
        "-find_in_path",
 #endif
+#ifdef FEAT_FLOAT
+       "+float",
+#else
+       "-float",
+#endif
 #ifdef FEAT_FOLDING
        "+folding",
 #else

Raspunde prin e-mail lui