I wanted to do some math in vim script to calculate for
example 80% of the rows vim uses in current window. So
I started to play with the devision operator and the
variables. It seems to me vim script just got integers?
echo 100 / 20 -> 5
echo 20 / 100 -> 0
echo 20.0 / 100.0 -> 2000
oh my, any help?
kind regards
Ralf
yep. There's not much need for floating point when doing
text-editing. It doesn't have built in support for trigonometric
functions, complex numbers or matrix math either.
If you just want percentages, you can do integer math on scaled
up numbers. Just remember to carry your scaling into
multipliers/divisors
> echo 100 / 20 -> 5
> echo 20 / 100 -> 0
> echo 20.0 / 100.0 -> 2000
>
> oh my, any help?
It's a horrible experience. I wrote a proof-of-concept
"AddDecimal" function which more or less did it via the
old-school method of "math by hand, lining up decimal points".
Lather/Rinse/Repeat for other operators in order to get
SubtractDecimal, MultiplyDecimal, and DivideDecimal. When
dividing, beware of repeating decimals.
It was sent to the ML in a thread entitled "Arithmetic", but I
can't for the life of me get Google to regurgitate a link to it.
Fortunately, I kept that post around as it was a nifty bit of
fun, so I've included it below.
Your best bet is to used a linked-in language (Vim can be built
with embedded access to Python, Perl, and Ruby...perhaps others?)
which are better suited for floating-point math.
-tim
function! AddDecimal(one, two)
if (match(a:one, '\.') < 0) && (match(a:two, '\.') < 0)
return a:one+a:two;
endif
if (match(a:one, '\.') < 0)
let l:onewhole = a:one
let l:onefrac = ''
else
let l:onewhole = substitute(a:one, '\..*', '', '')
let l:onefrac = substitute(a:one, '.*\.', '', '')
endif
if (match(a:two, '\.') < 0)
let l:twowhole = a:two
let l:twofrac = ''
else
let l:twowhole = substitute(a:two, '\..*', '', '')
let l:twofrac = substitute(a:two, '.*\.', '', '')
endif
let l:onefraclen = strlen(l:onefrac)
let l:twofraclen = strlen(l:twofrac)
if strlen(l:onefrac) > strlen(l:twofrac)
" use the length of onefrac
let l:decimalPlaces = strlen(l:onefrac)
else " use the length of twofrac
let l:decimalPlaces = strlen(l:twofrac)
endif
let l:counter = 0
let l:zeros = ''
while (l:counter < l:decimalPlaces)
let l:counter = l:counter + 1
let l:zeros = l:zeros.'0'
endw
let l:newone = l:onewhole.strpart(l:onefrac.l:zeros, 0,
l:decimalPlaces)
let l:newtwo = l:twowhole.strpart(l:twofrac.l:zeros, 0,
l:decimalPlaces)
" strip off leading zeroes which caused it to think the # was
octal
let l:newone = substitute(l:newone, '^\(-\=\)0*', '\1','')
let l:newtwo = substitute(l:newtwo, '^\(-\=\)0*', '\1', '')
" actually do the addition
let l:sum = l:newone+l:newtwo
" fix up to make sure things get realigned...this might be wrong
let l:sum = substitute(l:sum, '\(-\=\)\(.*\)',
'\1'.l:zeros.'\2', '')
" insert the decimal point back in visually
let l:sum = substitute(l:sum, '\(.\{'.l:decimalPlaces.'}\)$',
'.\1', '')
" strip out any leading or trailing zeros
let l:sum = substitute(l:sum, '^\(-\=\)0*\(.*\)0*$', '\1\2', '')
" clean it back up, putting a zero before the decimal pt if
no whole bit
let l:sum = substitute(l:sum, '^\(-\=\)\.', '\10.', '')
return l:sum
endfunction
function! TestPair(x, y)
echo substitute(' '.a:x, '.*\(.\{10}\)$', '\1', '')
echo substitute(' +'.a:y, '.*\(.\{10}\)$', '\1', '')
echo "=========="
echo substitute(' '.AddDecimal(a:x,a:y),
'.*\(.\{10}\)$', '\1', '')
echo "\n"
endfunction
function! TestAdding()
call TestPair('0.001', '0.02')
call TestPair('3.14', '0.08')
call TestPair('-4', '3.14')
call TestPair('-4.0', '3.141')
call TestPair('9.0001', '1.002')
call TestPair('1.0001', '-1.002')
call TestPair('0.0001', '-0.002')
endfunction
Use any of the language interfaces, perl, ruby you name it.
:perl VIM::Msg(20.0/100) -> 0.2
Make yourself familiar with your systems preferred calculator.
echo system('echo "scale=1;20.0/100.0"|bc') -> .2
Do you really need to know, that 80% of vims currently used
rows in a window equals 30.6152 ,or isn't 30 good enough ?
-ap
--
Ich hab geträumt, der Krieg wär vorbei.
To evaluate an equation (e.g., 2 + cos(3.1412)) I yank the
equation into the * register and hit \e; and the answer
(1.00000007708842) is echoed and also appears below the line the
cursor was on! This magic happens because I have mapped \e to the
thing that does the evaluation and echos the answer and pastes the
answer into the line below the cursor. The thing uses perl and
is:
" evaluate numerical expression in unnammed buffer
" and echo and append result
nmap \e :perl my $foo = eval(VIM::Eval('@*'));
\ VIM::DoCommand("let @* = '" . $foo . " '" );
\ my @pos = $curwin->Cursor();
\ $curbuf->Append($pos[0], $foo);
\ VIM::Msg($foo);<CR>
--Suresh
Kevin
> Ralf asked:
> >
> > I wanted to do some math in vim script to calculate for example
> > 80% of the rows vim uses in current window. So I started to play
> > with the devision operator and the variables. It seems to me vim
> > script just got integers?
> >
> > echo 100 / 20 -> 5
> > echo 20 / 100 -> 0
> > echo 20.0 / 100.0 -> 2000
> >
>
> I wanted to do some math in vim script to calculate for
> example 80% of the rows vim uses in current window. So
> I started to play with the devision operator and the
> variables. It seems to me vim script just got integers?
For integer percentages with rounding, i.e. calculate p% of n:
echo (n*p+50)/100
For more complex math, check out using BC with:
http://vim.sourceforge.net/tips/tip.php?tip_id=1349
--
Best regards,
Bill
> I wanted to do some math in vim script to calculate for
> example 80% of the rows vim uses in current window. So
> I started to play with the devision operator and the
> variables. It seems to me vim script just got integers?
For integer percentages with rounding, i.e. calculate p% of n:
Hi Bill, I see you made valuable comments in that tip, and I can see why you
linked to the old tip site (because the import has destroyed the formatting
in this tip on the new site).
Any chance you could get inspired to fix the imported tip at
http://vim.wikia.com/wiki/VimTip1349
Preferably, you would create an account and logon, but that's optional. Then
you would click Edit and, well, you would edit. Since the imported tip is a
bit of a mess, you might copy the text out of the browser edit box into Vim,
and work there.
Here's what's needed:
* Delete the stupid blank lines that somehow were inserted during the
import. Ideally, you would join the lines in a paragraph (on the wiki, a
paragraph is a single line that wraps; use one blank line between paras).
* Insert a new line before and after each block of code, like this:
<pre>
" Here is some stuff that you want in a fixed-width font.
" It will appear exactly as typed.
</pre>
* Fix the code indents (most of these were screwed up by the import).
Sometimes I just copy the text from the old tip. I find that two-space
indents work pretty well on the wiki (although I would use four in my code).
* Optional: Replace ":help :s\=" with "{{help|id=:s\=}}" (click the "General
guidelines" in the Review box at the top of the tip to lead to docs on
Template:Help).
* This tip uses a bar ('|') and unfortunately the import does something
tricky which breaks when a bar is used. The solution is to find the "}}"
just before "== Comments ==". Delete the "}}" line. At the top of the tip,
insert the "}}" line followed by a blank line, just after the line "|text=".
You would end up with:
---begin---
|text=
}}
This tip is to add a good calculator....
---end---
In the "Summary" box, write something like "Fixed formatting".
Click the "Show Preview" button to see if it worked, then "Save".
Yes, I could have fixed the tip myself ... but we really need some help on
the wiki folks! Please try it.
John
In order to calculate 80% of the lines, instead of
&lines * 0.8
do:
&lines * 80 / 100
You can multiply numbers with some factor to move the decimal place to
the right. For fancier stuff, you'll have to "resort" to builtin-perl/
python/ruby etc. if available.
Essentially that's what I do for Mines.vim ; it uses integer arithmetic
to report the success rate to the third decimal place.
I also use my own program, calc, to do floating point calculations when
I need them, along with some maps to make that easier.
Regards,
Chip Campbell
Same as I do. If anybody wants to have look at the possible mappings,
check http://wyw.dcweb.cn/vim/_vimrc.html and search for "arithmetic".
I use my own calcu program on Windows (Microsoft has used the name
"calc" already). On Linux I use this simple script:
#! /bin/sh
echo "$*" | sed -e $'s/\r$//' -e 's/sin *(/s(/g' -e 's/cos *(/c(/g' -e
's/atan *(/a(/g' -e 's/log *(/l(/g' -e 's/exp *(/e(/g' | bc -l
Best regards,
Yongwei
--
Wu Yongwei
URL: http://wyw.dcweb.cn/
> Essentially that's what I do for Mines.vim
Now that is a fun thing. Are there any other games for vim?
Richard
There are a few that are distributed with Vim. Check the subfolders of
$VIMRUNTIME/macros/.
Best regards,
Tony.
--
Today is the tomorrow you worried about yesterday
> There are a few that are distributed with Vim. Check the subfolders of
> $VIMRUNTIME/macros/.
Thanks.
Richard
There are much better games on vim.org scripts section. There is even a
subsection called games for you to search.
There is a lot of noise, but the first few are the good ones.
--
Hari
>
> Thanks.
>
>
> Richard
>
> >
>