Since C++ (Java, Python, etc...) have support for binary literals now, I'm
trying to add support for a 'bin' nrformat. So far, I've been able to add it
to sort, increment/decrement, key parsing, and some other various functions.
I would still need to add some tests, but I was hoping to get feedback on what
I have so far. As it currently works it could double the stack space used for
ASCII numbers (30 -> sizeof(unsigned long) * 8), so I thought that may be one
concern.
This 'bin' nrformat actually ties into another feature I was considering (radix
conversion), so any feedback is much appreciated.
-Jason
--
--
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
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff --git a/src/charset.c b/src/charset.c
index a74bf0d..dd6cafc 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -1570,6 +1570,19 @@ skipdigits(q)
#if defined(FEAT_SYN_HL) || defined(FEAT_SPELL) || defined(PROTO)
/*
+ * skip over binary digits
+ */
+ char_u *
+skipbin(q)
+ char_u *q;
+{
+ char_u *p = q;
+
+ while (vim_isbdigit(*p)) /* skip to next non-digit */
+ ++p;
+ return p;
+}
+/*
* skip over digits and hex characters
*/
char_u *
@@ -1586,6 +1599,19 @@ skiphex(q)
#if defined(FEAT_EX_EXTRA) || defined(PROTO)
/*
+ * skip to bin digit (or NUL after the string)
+ */
+ char_u *
+skiptobin(q)
+ char_u *q;
+{
+ char_u *p = q;
+
+ while (*p != NUL && !vim_isbdigit(*p)) /* skip to next digit */
+ ++p;
+ return p;
+}
+/*
* skip to digit (or NUL after the string)
*/
char_u *
@@ -1641,6 +1667,16 @@ vim_isxdigit(c)
|| (c >= 'A' && c <= 'F');
}
+/*
+ * Corallary of vim_isdigit and vim_isxdigit() that can handle characters > 0x100.
+ */
+ int
+vim_isbdigit(c)
+ int c;
+{
+ return (c == '0' || c == '1');
+}
+
#if defined(FEAT_MBYTE) || defined(PROTO)
/*
* Vim's own character class functions. These exist because many library
@@ -1822,15 +1858,19 @@ vim_isblankline(lbuf)
/*
* Convert a string into a long and/or unsigned long, taking care of
- * hexadecimal and octal numbers. Accepts a '-' sign.
+ * hexadecimal, octal, and binary numbers. Accepts a '-' sign.
* If "hexp" is not NULL, returns a flag to indicate the type of the number:
* 0 decimal
* '0' octal
+ * 'B' bin
+ * 'b' bin
* 'X' hex
* 'x' hex
* If "len" is not NULL, the length of the number in characters is returned.
* If "nptr" is not NULL, the signed result is returned in it.
* If "unptr" is not NULL, the unsigned result is returned in it.
+ * If "dobin" is non-zero recognize bin numbers, when > 1 always assume
+ * bin number.
* If "dooct" is non-zero recognize octal numbers, when > 1 always assume
* octal number.
* If "dohex" is non-zero recognize hex numbers, when > 1 always assume
@@ -1838,11 +1878,12 @@ vim_isblankline(lbuf)
* If maxlen > 0, check at a maximum maxlen chars
*/
void
-vim_str2nr(start, hexp, len, dooct, dohex, nptr, unptr, maxlen)
+vim_str2nr(start, hexp, len, dobin, dooct, dohex, nptr, unptr, maxlen)
char_u *start;
int *hexp; /* return: type of number 0 = decimal, 'x'
- or 'X' is hex, '0' = octal */
+ or 'X' is hex, '0' = octal, 'b' or 'B' is bin */
int *len; /* return: detected length of number */
+ int dobin; /* recognize bin number */
int dooct; /* recognize octal number */
int dohex; /* recognize hex number */
long *nptr; /* return: signed result */
@@ -1861,7 +1902,7 @@ vim_str2nr(start, hexp, len, dooct, dohex, nptr, unptr, maxlen)
++ptr;
}
- /* Recognize hex and octal. */
+ /* Recognize hex, octal, and bin. */
if (ptr[0] == '0' && ptr[1] != '8' && ptr[1] != '9'
&& (maxlen == 0 || maxlen > 1))
{
@@ -1869,6 +1910,9 @@ vim_str2nr(start, hexp, len, dooct, dohex, nptr, unptr, maxlen)
if (dohex && (hex == 'X' || hex == 'x') && vim_isxdigit(ptr[2])
&& (maxlen == 0 || maxlen > 2))
ptr += 2; /* hexadecimal */
+ else if (dobin && (hex == 'B' || hex == 'b') && vim_isbdigit(ptr[2])
+ && (maxlen == 0 || maxlen > 2))
+ ptr += 2; /* binary */
else
{
hex = 0; /* default is decimal */
@@ -1895,7 +1939,20 @@ vim_str2nr(start, hexp, len, dooct, dohex, nptr, unptr, maxlen)
* Do the string-to-numeric conversion "manually" to avoid sscanf quirks.
*/
n = 1;
- if (hex == '0' || dooct > 1)
+ if (hex == 'B' || hex == 'b' || dobin > 1)
+ {
+ /* bin */
+ if (hex != 0)
+ n += 2; /* skip over "0b" */
+ while ('0' <= *ptr && *ptr <= '1')
+ {
+ un = 2 * un + (unsigned long)(*ptr - '0');
+ ++ptr;
+ if (n++ == maxlen)
+ break;
+ }
+ }
+ else if (hex == '0' || dooct > 1)
{
/* octal */
while ('0' <= *ptr && *ptr <= '7')
diff --git a/src/eval.c b/src/eval.c
index e12813c..42786ca 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1620,7 +1620,7 @@ call_vim_function(func, argc, argv, safe, str_arg_only, rettv)
len = 0;
else
/* Recognize a number argument, the others must be strings. */
- vim_str2nr(argv[i], NULL, &len, TRUE, TRUE, &n, NULL, 0);
+ vim_str2nr(argv[i], NULL, &len, TRUE, TRUE, TRUE, &n, NULL, 0);
if (len != 0 && len == (int)STRLEN(argv[i]))
{
argvars[i].v_type = VAR_NUMBER;
@@ -5134,7 +5134,7 @@ eval7(arg, rettv, evaluate, want_string)
else
#endif
{
- vim_str2nr(*arg, NULL, &len, TRUE, TRUE, &n, NULL, 0);
+ vim_str2nr(*arg, NULL, &len, TRUE, TRUE, TRUE, &n, NULL, 0);
*arg += len;
if (evaluate)
{
@@ -18361,7 +18361,7 @@ f_str2nr(argvars, rettv)
if (argvars[1].v_type != VAR_UNKNOWN)
{
base = get_tv_number(&argvars[1]);
- if (base != 8 && base != 10 && base != 16)
+ if (base != 2 && base != 8 && base != 10 && base != 16)
{
EMSG(_(e_invarg));
return;
@@ -18371,7 +18371,7 @@ f_str2nr(argvars, rettv)
p = skipwhite(get_tv_string(&argvars[0]));
if (*p == '+')
p = skipwhite(p + 1);
- vim_str2nr(p, NULL, NULL, base == 8 ? 2 : 0, base == 16 ? 2 : 0, &n, NULL, 0);
+ vim_str2nr(p, NULL, NULL, base == 2 ? 2 : 0, base == 8 ? 2 : 0, base == 16 ? 2 : 0, &n, NULL, 0);
rettv->vval.v_number = n;
}
@@ -21177,7 +21177,7 @@ get_tv_number_chk(varp, denote)
case VAR_STRING:
if (varp->vval.v_string != NULL)
vim_str2nr(varp->vval.v_string, NULL, NULL,
- TRUE, TRUE, &n, NULL, 0);
+ TRUE, TRUE, TRUE, &n, NULL, 0);
return n;
case VAR_LIST:
EMSG(_("E745: Using a List as a Number"));
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index c2b600c..ab69628 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -365,6 +365,7 @@ ex_sort(eap)
long deleted;
colnr_T start_col;
colnr_T end_col;
+ int sort_bin; /* sort on bin number */
int sort_oct; /* sort on octal number */
int sort_hex; /* sort on hex number */
@@ -381,7 +382,7 @@ ex_sort(eap)
if (nrs == NULL)
goto sortend;
- sort_abort = sort_ic = sort_rx = sort_nr = sort_oct = sort_hex = 0;
+ sort_abort = sort_ic = sort_rx = sort_nr = sort_bin = sort_oct = sort_hex = 0;
for (p = eap->arg; *p != NUL; ++p)
{
@@ -393,6 +394,8 @@ ex_sort(eap)
sort_rx = TRUE;
else if (*p == 'n')
sort_nr = 2;
+ else if (*p == 'b')
+ sort_bin = 2;
else if (*p == 'o')
sort_oct = 2;
else if (*p == 'x')
@@ -439,15 +442,15 @@ ex_sort(eap)
}
}
- /* Can only have one of 'n', 'o' and 'x'. */
- if (sort_nr + sort_oct + sort_hex > 2)
+ /* Can only have one of 'n', 'b', 'o' and 'x'. */
+ if (sort_nr + sort_bin + sort_oct + sort_hex > 2)
{
EMSG(_(e_invarg));
goto sortend;
}
/* From here on "sort_nr" is used as a flag for any number sorting. */
- sort_nr += sort_oct + sort_hex;
+ sort_nr += sort_bin + sort_oct + sort_hex;
/*
* Make an array with all line numbers. This avoids having to copy all
@@ -491,6 +494,8 @@ ex_sort(eap)
p = s + start_col;
if (sort_hex)
s = skiptohex(p);
+ else if (sort_bin)
+ s = skiptobin(p);
else
s = skiptodigit(p);
if (s > p && s[-1] == '-')
@@ -499,7 +504,7 @@ ex_sort(eap)
/* empty line should sort before any number */
nrs[lnum - eap->line1].start_col_nr = -MAXLNUM;
else
- vim_str2nr(s, NULL, NULL, sort_oct, sort_hex,
+ vim_str2nr(s, NULL, NULL, sort_bin, sort_oct, sort_hex,
&nrs[lnum - eap->line1].start_col_nr, NULL, 0);
*s2 = c;
}
diff --git a/src/ex_getln.c b/src/ex_getln.c
index 0aeb4b8..8bf2b7e 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -5935,7 +5935,7 @@ get_list_range(str, num1, num2)
*str = skipwhite(*str);
if (**str == '-' || vim_isdigit(**str)) /* parse "from" part of range */
{
- vim_str2nr(*str, NULL, &len, FALSE, FALSE, &num, NULL, 0);
+ vim_str2nr(*str, NULL, &len, FALSE, FALSE, FALSE, &num, NULL, 0);
*str += len;
*num1 = (int)num;
first = TRUE;
@@ -5944,7 +5944,7 @@ get_list_range(str, num1, num2)
if (**str == ',') /* parse "to" part of range */
{
*str = skipwhite(*str + 1);
- vim_str2nr(*str, NULL, &len, FALSE, FALSE, &num, NULL, 0);
+ vim_str2nr(*str, NULL, &len, FALSE, FALSE, FALSE, &num, NULL, 0);
if (len > 0)
{
*num2 = (int)num;
diff --git a/src/misc2.c b/src/misc2.c
index 3f1568d..b8bf444 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -2776,7 +2776,7 @@ find_special_key(srcp, modp, keycode, keep_x_key)
bp += 3; /* skip t_xx, xx may be '-' or '>' */
else if (STRNICMP(bp, "char-", 5) == 0)
{
- vim_str2nr(bp + 5, NULL, &l, TRUE, TRUE, NULL, NULL, 0);
+ vim_str2nr(bp + 5, NULL, &l, TRUE, TRUE, TRUE, NULL, NULL, 0);
bp += l + 5;
break;
}
@@ -2808,7 +2808,7 @@ find_special_key(srcp, modp, keycode, keep_x_key)
&& VIM_ISDIGIT(last_dash[6]))
{
/* <Char-123> or <Char-033> or <Char-0x33> */
- vim_str2nr(last_dash + 6, NULL, NULL, TRUE, TRUE, NULL, &n, 0);
+ vim_str2nr(last_dash + 6, NULL, NULL, TRUE, TRUE, TRUE, NULL, &n, 0);
key = (int)n;
}
else
diff --git a/src/ops.c b/src/ops.c
index d099580..647e0e0 100644
--- a/src/ops.c
+++ b/src/ops.c
@@ -5383,7 +5383,7 @@ do_addsub(command, Prenum1, g_cmd)
int col;
char_u *buf1;
char_u buf2[NUMBUFLEN];
- int hex; /* 'X' or 'x': hex; '0': octal */
+ int hex; /* 'X' or 'x': hex; '0': octal; 'B' or 'b': bin */
static int hexupper = FALSE; /* 0xABC */
unsigned long n;
unsigned long offset = 0; /* line offset for Ctrl_V mode */
@@ -5394,6 +5394,7 @@ do_addsub(command, Prenum1, g_cmd)
int todel;
int dohex;
int dooct;
+ int dobin;
int doalp;
int firstdigit;
int subtract;
@@ -5407,9 +5408,13 @@ do_addsub(command, Prenum1, g_cmd)
int did_change = FALSE;
pos_T t = curwin->w_cursor;
int maxlen = 0;
+ int pos = 0;
+ int bit = 0;
+ int bits = sizeof(unsigned long) * 8;
dohex = (vim_strchr(curbuf->b_p_nf, 'x') != NULL); /* "heX" */
dooct = (vim_strchr(curbuf->b_p_nf, 'o') != NULL); /* "Octal" */
+ dobin = (vim_strchr(curbuf->b_p_nf, 'b') != NULL); /* "Bin" */
doalp = (vim_strchr(curbuf->b_p_nf, 'p') != NULL); /* "alPha" */
/*
@@ -5458,17 +5463,45 @@ do_addsub(command, Prenum1, g_cmd)
ptr = ml_get_curline();
RLADDSUBFIX(ptr);
- if (dohex)
- while (col > 0 && vim_isxdigit(ptr[col]))
+ if (dobin)
+ while (col > 0 && vim_isbdigit(ptr[col]))
--col;
- if ( dohex
+
+ if (dohex)
+ while (col > 0 && vim_isxdigit(ptr[col]))
+ --col;
+
+ if ( dobin
+ && dohex
+ && ! ((col > 0
+ && (ptr[col] == 'X'
+ || ptr[col] == 'x')
+ && ptr[col - 1] == '0'
+ && vim_isxdigit(ptr[col + 1]))))
+ {
+
+ /* In case of binary/hexadecimal pattern overlap match, rescan */
+
+ col = curwin->w_cursor.col;
+
+ while (col > 0 && vim_isdigit(ptr[col]))
+ col--;
+ }
+
+ if (( dohex
&& col > 0
&& (ptr[col] == 'X'
|| ptr[col] == 'x')
&& ptr[col - 1] == '0'
- && vim_isxdigit(ptr[col + 1]))
+ && vim_isxdigit(ptr[col + 1])) ||
+ ( dobin
+ && col > 0
+ && (ptr[col] == 'B'
+ || ptr[col] == 'b')
+ && ptr[col - 1] == '0'
+ && vim_isbdigit(ptr[col + 1])))
{
- /* Found hexadecimal number, move to its start. */
+ /* Found hexadecimal or binary number, move to its start. */
--col;
}
else
@@ -5613,10 +5646,10 @@ do_addsub(command, Prenum1, g_cmd)
: curwin->w_cursor.col - col + 1);
}
- vim_str2nr(ptr + col, &hex, &length, dooct, dohex, NULL, &n,
+ vim_str2nr(ptr + col, &hex, &length, dobin, dooct, dohex, NULL, &n,
maxlen);
- /* ignore leading '-' for hex and octal numbers */
+ /* ignore leading '-' for hex and octal and bin numbers */
if (hex && negative)
{
++col;
@@ -5715,7 +5748,8 @@ do_addsub(command, Prenum1, g_cmd)
*ptr++ = '0';
--length;
}
- if (hex == 'x' || hex == 'X')
+ if (hex == 'b' || hex == 'B' ||
+ hex == 'x' || hex == 'X')
{
*ptr++ = hex;
--length;
@@ -5724,7 +5758,18 @@ do_addsub(command, Prenum1, g_cmd)
/*
* Put the number characters in buf2[].
*/
- if (hex == 0)
+ if (hex == 'b' || hex == 'B')
+ {
+ /* leading zeros */
+ for (bit = bits; bit > 0; bit--)
+ if ((n >> (bit - 1)) & 0x1) break;
+
+ for (pos = 0; bit > 0; bit--)
+ buf2[pos++] = ((n >> (bit - 1)) & 0x1) ? '1' : '0';
+
+ buf2[pos] = '\0';
+ }
+ else if (hex == 0)
sprintf((char *)buf2, "%lu", n);
else if (hex == '0')
sprintf((char *)buf2, "%lo", n);
diff --git a/src/option.c b/src/option.c
index f8cb1ba..963d108 100644
--- a/src/option.c
+++ b/src/option.c
@@ -1944,7 +1944,7 @@ static struct vimoption
{(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
{"nrformats", "nf", P_STRING|P_ALLOCED|P_VI_DEF|P_ONECOMMA|P_NODUP,
(char_u *)&p_nf, PV_NF,
- {(char_u *)"octal,hex", (char_u *)0L}
+ {(char_u *)"bin,octal,hex", (char_u *)0L}
SCRIPTID_INIT},
{"number", "nu", P_BOOL|P_VI_DEF|P_RWIN,
(char_u *)VAR_WIN, PV_NU,
@@ -3051,7 +3051,7 @@ static struct vimoption
static char *(p_ambw_values[]) = {"single", "double", NULL};
#endif
static char *(p_bg_values[]) = {"light", "dark", NULL};
-static char *(p_nf_values[]) = {"octal", "hex", "alpha", NULL};
+static char *(p_nf_values[]) = {"bin", "octal", "hex", "alpha", NULL};
static char *(p_ff_values[]) = {FF_UNIX, FF_DOS, FF_MAC, NULL};
#ifdef FEAT_CRYPT
static char *(p_cm_values[]) = {"zip", "blowfish", "blowfish2", NULL};
@@ -4600,7 +4600,7 @@ do_set(arg, opt_flags)
{
/* Allow negative (for 'undolevels'), octal and
* hex numbers. */
- vim_str2nr(arg, NULL, &i, TRUE, TRUE, &value, NULL, 0);
+ vim_str2nr(arg, NULL, &i, TRUE, TRUE, TRUE, &value, NULL, 0);
if (arg[i] != NUL && !vim_iswhite(arg[i]))
{
errmsg = e_invarg;
diff --git a/src/proto/charset.pro b/src/proto/charset.pro
index dd3b6f2..a650eb9 100644
--- a/src/proto/charset.pro
+++ b/src/proto/charset.pro
@@ -35,11 +35,14 @@ colnr_T getvcol_nolist __ARGS((pos_T *posp));
void getvvcol __ARGS((win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *end));
void getvcols __ARGS((win_T *wp, pos_T *pos1, pos_T *pos2, colnr_T *left, colnr_T *right));
char_u *skipwhite __ARGS((char_u *q));
+char_u *skipbin __ARGS((char_u *q));
char_u *skipdigits __ARGS((char_u *q));
char_u *skiphex __ARGS((char_u *q));
char_u *skiptodigit __ARGS((char_u *q));
+char_u *skiptobin __ARGS((char_u *q));
char_u *skiptohex __ARGS((char_u *q));
int vim_isdigit __ARGS((int c));
+int vim_isbdigit __ARGS((int c));
int vim_isxdigit __ARGS((int c));
int vim_islower __ARGS((int c));
int vim_isupper __ARGS((int c));
@@ -49,7 +52,7 @@ char_u *skiptowhite __ARGS((char_u *p));
char_u *skiptowhite_esc __ARGS((char_u *p));
long getdigits __ARGS((char_u **pp));
int vim_isblankline __ARGS((char_u *lbuf));
-void vim_str2nr __ARGS((char_u *start, int *hexp, int *len, int dooct, int dohex, long *nptr, unsigned long *unptr, int strlen));
+void vim_str2nr __ARGS((char_u *start, int *hexp, int *len, int dobin, int dooct, int dohex, long *nptr, unsigned long *unptr, int strlen));
int hex2nr __ARGS((int c));
int hexhex2nr __ARGS((char_u *p));
int rem_backslash __ARGS((char_u *str));
diff --git a/src/spell.c b/src/spell.c
index 5d9c0cc..9649f39 100644
--- a/src/spell.c
+++ b/src/spell.c
@@ -1047,7 +1047,9 @@ spell_check(wp, ptr, attrp, capcol, docount)
* julifeest". */
if (*ptr >= '0' && *ptr <= '9')
{
- if (*ptr == '0' && (ptr[1] == 'x' || ptr[1] == 'X'))
+ if (*ptr == '0' && (ptr[1] == 'b' || ptr[1] == 'B'))
+ mi.mi_end = skipbin(ptr + 2);
+ else if (*ptr == '0' && (ptr[1] == 'x' || ptr[1] == 'X'))
mi.mi_end = skiphex(ptr + 2);
else
mi.mi_end = skipdigits(ptr);
diff --git a/src/testdir/test57.in b/src/testdir/test57.in
index 8d972e4..ed35df0 100644
--- a/src/testdir/test57.in
+++ b/src/testdir/test57.in
@@ -30,6 +30,7 @@ STARTTEST
:/^t25:/+1,/^t26/-1sort/\d\d/rn
:/^t26:/+1,/^t27/-1sort/\d\d/rx
:/^t27:/+1,/^t28/-1sort no
+:/^t28:/+1,/^t29/-1sort b
:/^t01:/,$wq! test.out
ENDTEST
@@ -494,7 +495,22 @@ c321d
b322b
b321
b321b
-
-
-t28: done
+t28: binary
+
+
+0b111000
+0b101100
+0b101001
+0b101001
+0b101000
+0b000000
+0b001000
+0b010000
+0b101000
+0b100000
+0b101010
+0b100010
+0b100100
+0b100010
+t29: done
diff --git a/src/testdir/test57.ok b/src/testdir/test57.ok
index aa3d373..3a119fd 100644
--- a/src/testdir/test57.ok
+++ b/src/testdir/test57.ok
@@ -453,7 +453,22 @@ c321d
b322b
b321
b321b
-
-
-t28: done
+t28: binary
+
+
+0b000000
+0b001000
+0b010000
+0b100000
+0b100010
+0b100010
+0b100100
+0b101000
+0b101000
+0b101001
+0b101001
+0b101010
+0b101100
+0b111000
+t29: done
diff --git a/src/testdir/test_increment.in b/src/testdir/test_increment.in
index 2ae6b8a..658aa21 100644
--- a/src/testdir/test_increment.in
+++ b/src/testdir/test_increment.in
@@ -286,6 +286,25 @@ Text:
1) Ctrl-V f3 <ctrl-a>
0x124456
+22) Block increment on 0b0
+Text:
+0b1
+0b1
+ Expected:
+ 1) Ctrl-A on visually block selected region (cursor at beginning):
+ 0b10
+ 0b10
+ 2) Ctrl-A on visually block selected region (cursor at end)
+ 0b10
+ 0b10
+
+23) block-wise increment on part of binary
+Text:
+0b1001
+
+ Expected:
+ 1) Ctrl-V 5l <ctrl-a>
+0b1011
STARTTEST
@@ -415,6 +434,18 @@ V3kg..
:set nrformats&vim
f3
+:" Test 22
+:/^S22=/+,/^E22=/-y a
+:/^E22=/+put a
+kj$j:.+put a
+k$+
+
+:" Test 23
+:/^S23=/+,/^E23=/-y a
+:/^E23=/+put a
+:set nrformats&vim
+4l
+
:" Save the report
:/^# Test 1/,$w! test.out
:qa!
@@ -615,6 +646,21 @@ E21====
+# Test 22
+S22====
+0b1
+0b1
+E22====
+
+
+
+
+# Test 23
+S23====
+0b1001
+E23====
+
+
ENDTEST
diff --git a/src/testdir/test_increment.ok b/src/testdir/test_increment.ok
index 15d0e9b..6297b9b 100644
--- a/src/testdir/test_increment.ok
+++ b/src/testdir/test_increment.ok
@@ -288,6 +288,26 @@ E21====
0x124456
+# Test 22
+S22====
+0b1
+0b1
+E22====
+
+0b10
+0b10
+
+0b10
+0b10
+
+
+# Test 23
+S23====
+0b1001
+E23====
+
+0b1011
+
ENDTEST
diff --git a/src/vim.h b/src/vim.h
index 809f312..eab8ed7 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -392,7 +392,7 @@
# endif
#endif
-#define NUMBUFLEN 30 /* length of a buffer to store a number in ASCII */
+#define NUMBUFLEN (sizeof(unsigned long) * 8) /* length of a buffer to store a number in ASCII */
/*
* Shorthand for unsigned variables. Many systems, but not all, have u_char