On 15/12/11 19:33, Bram Moolenaar wrote:

Ben Fritz wrote:

On Dec 14, 8:33 am, Bram Moolenaar<[email protected]>  wrote:
Patch 7.3.377
Problem:    No support for bitwise AND, OR, XOR and invert.
Solution:   Add add(), or(), invert() and xor() functions.
Files:      src/eval.c, src/testdir/test49.in, src/testdir/test65.in,
             src/testdir/test65.ok, runtime/doc/eval.txt


A couple of things:

1. I note that the new functions are missing from :help function-list
(probably they should be under a new subheading, like "integer
computation" or "bitwise computation" similar to "floating point
computation").

Indeed, I'll add them there.

2. I note that no shift operators were defined. So now the easiest way
to do the shifting if needed is by multiplying or dividing by powers
of 2. But I just realized pow() is a floating-point function, making a
shift much more expensive than it needs to be, if this function is
used. I could not find a good way to get arbitrary (integer) powers of
2 with Vim functions/syntax. Can we either add the shift operators, or
add the ability to do integer exponentiation?

I haven't decided yet.  In most cases you can simple do var * 2 or
var / 2.  Only for very big numbers that may not work right.
If you really need to shift by something that is not a constant then
indeed it is more complicated.


The following should be fast enough but I haven't tested it. It can all go in the vimrc or in a global plugin.



" Initialization. This implicitly takes sizeof(int) into account.
let PowersOfTwo = []
let n = 1
while n " n==0 means no error on overflow
        try
                let PowersOfTwo += [n]
                let n += n
        catch   " if error on overflow
                break
        endtry
endwhile

" Auxiliary functions
func Pow2(x)
        try
                return PowersOfTwo[a:x]
        catch
                return -1
        endtry
endfunc
func LeftShift(value, shift)
        if a:shift < 0
                return RightShift(a:value, - a:shift)
        endif
        try
                let l:cpo = &cpo
                set cpo&vim " recognise continuation lines
                let s = Pow2(a:shift)
                if s != -1
                        return a:value * s
                endif
        " errors are intentionally not caught
                throw "Invalid arguments: LeftShift(" . a:value . ", "
                        \ . a:shift . ")"
        finally
                let &cpo = l:cpo
        endtry
endfunc
func RightShift(value, shift)
        if a:shift < 0
                return LeftShift(a:value, - a:shift)
        endif
        try
                let l:cpo = &cpo
                set cpo&vim
                let s = Pow2(a:shift)
                if s != -1
                        return a:value / s
                endif
                throw "Invalid arguments: RightShift(" . a:value . ", "
                        \ . a:shift . ")"
        finally
                let &cpo = l:cpo
        endtry
endfunc




Best regards,
Tony.
--
"People think love is an emotion.  Love is good sense."
                -- Ken Kesey

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