Updated floating point patch

18 views
Skip to first unread message

Bram Moolenaar

unread,
Jun 8, 2008, 12:19:04 PM6/8/08
to vim...@vim.org
Attached you will find the latest floating point patch. This goes on
top of the current Vim sources (7.1.311). If you included a previous
version of the floating point patch you need to remove that first.

In this version 123.456 is seen as a floating point number. So there is
no longer the weird syntax &123.456. This is a tiny backwards
compatibility problem. Which is one of the reasons for you to try this
out. Does this break any script?

Another change is using strtod() instead of our own code for converting
text to a floating point number. This works much better for overflows.
It does require the LC_NUMERIC value of the locale to be set to "C".
Otherwise a comma might be used in some situations, which would be very
confusing. Please check if this works correctly:

echo 0.9999999999999999999999999999999999

The result should be "1.000000".

Let's give this some testing. If there are no serious problems I plan
to add this in Vim 7.2 (whenever that is ready).

-
hundred-and-one symptoms of being an internet addict:
16. You step out of your room and realize that your parents have moved and
you don't have a clue when it happened.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ download, build and distribute -- http://www.A-A-P.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///

floating_point_patch

Bill McCarthy

unread,
Jun 8, 2008, 2:41:25 PM6/8/08
to Vim Developers, Bram Moolenaar
On Sun 8-Jun-08 11:19am -0600, Bram Moolenaar wrote:

> Attached you will find the latest floating point patch. This goes on
> top of the current Vim sources (7.1.311). If you included a previous
> version of the floating point patch you need to remove that first.
>
> In this version 123.456 is seen as a floating point number. So there is
> no longer the weird syntax &123.456. This is a tiny backwards
> compatibility problem. Which is one of the reasons for you to try this
> out. Does this break any script?
>
> Another change is using strtod() instead of our own code for converting
> text to a floating point number. This works much better for overflows.
> It does require the LC_NUMERIC value of the locale to be set to "C".
> Otherwise a comma might be used in some situations, which would be very
> confusing. Please check if this works correctly:
>
> echo 0.9999999999999999999999999999999999
>
> The result should be "1.000000".

That echo test performed correctly before applying the new
patch. I'm using your original April patch, John Beckett's
patch and your patch of 6/5 to allow not using '&'.

I have a couple of questions before I test with this patch.
(1) does this obviate the need for Mr. Beckett's patch? (2)
does this LC_NUMERIC actually work on Windows - I recall
having problems with LC_ALL using the unix sort of GNU
coreutils - is this an environment variable we need to set?

--
Best regards,
Bill

Bram Moolenaar

unread,
Jun 8, 2008, 5:25:24 PM6/8/08
to Bill McCarthy, Vim Developers

Bill McCarthy wrote:

> On Sun 8-Jun-08 11:19am -0600, Bram Moolenaar wrote:
>
> > Attached you will find the latest floating point patch. This goes on
> > top of the current Vim sources (7.1.311). If you included a previous
> > version of the floating point patch you need to remove that first.
> >
> > In this version 123.456 is seen as a floating point number. So there is
> > no longer the weird syntax &123.456. This is a tiny backwards
> > compatibility problem. Which is one of the reasons for you to try this
> > out. Does this break any script?
> >
> > Another change is using strtod() instead of our own code for converting
> > text to a floating point number. This works much better for overflows.
> > It does require the LC_NUMERIC value of the locale to be set to "C".
> > Otherwise a comma might be used in some situations, which would be very
> > confusing. Please check if this works correctly:
> >
> > echo 0.9999999999999999999999999999999999
> >
> > The result should be "1.000000".
>
> That echo test performed correctly before applying the new
> patch. I'm using your original April patch, John Beckett's
> patch and your patch of 6/5 to allow not using '&'.
>
> I have a couple of questions before I test with this patch.
> (1) does this obviate the need for Mr. Beckett's patch?

No, you don't need anything else. The strtod() function replaces most
of what John Becket wrote.

> (2) does this LC_NUMERIC actually work on Windows - I recall having
> problems with LC_ALL using the unix sort of GNU
> coreutils - is this an environment variable we need to set?

I haven't tried it. So please set your environment so that a comma is
used for a decimal point and then run Vim to try out the floating point
stuff.

--

hundred-and-one symptoms of being an internet addict:

18. Your wife drapes a blond wig over your monitor to remind you of what she
looks like.

Bill McCarthy

unread,
Jun 8, 2008, 9:43:58 PM6/8/08
to Vim Developers, Bram Moolenaar
On Sun 8-Jun-08 4:25pm -0600, Bram Moolenaar wrote:
> Bill McCarthy wrote:

>> (2) does this LC_NUMERIC actually work on Windows - I recall having
>> problems with LC_ALL using the unix sort of GNU
>> coreutils - is this an environment variable we need to set?

> I haven't tried it. So please set your environment so that a comma is
> used for a decimal point and then run Vim to try out the floating point
> stuff.

The patch applied flawlessly. Both Vim and Gvim makes were
without warnings.

Without setting any environment variables,all of my tests
are working as expected.

Also, commas don't work as expected. Here's what I get
from:

:echo 1,2

1
E15: Invalid expression: ,2
E15: Invalid expression: ,2

--
Best regards,
Bill

Tony Mechelynck

unread,
Jun 9, 2008, 3:01:13 AM6/9/08
to vim...@googlegroups.com, Bram Moolenaar

I get the same but I think it's expected -- at least with my locale

:lang
Current language:
"LC_CTYPE=en_US.UTF-8;LC_NUMERIC=C;LC_TIME=C;LC_COLLATE=C;LC_MONETARY=C;LC_MESSAGES=C;LC_PAPER=C;LC_NAME=C;LC_ADDRESS=C;LC_TELEPHONE=C;LC_MEASUREMENT=C;LC_IDENTIFICATION=C"

When I was on Windows, it didn't accept C as a locale but it did accept
en so, since I wanted menus and messages in English and not in the
French or Dutch of my Windows locale, I started my vimrc with

if has("unix")
language messages C
else
language messages en
endif
runtime vimrc_example.vim

etc. Since Vim has no separate ":language numeric" setting, I suppose it
should be set with ":language en" or similar. If you want to keep
messages and/or ctype and/or time in your default locale, you'll need to
save and restore them, for instance:

let save_messages = v:lang
let save_time = v:lc_time
let save_ctype = v:ctype
if has("unix")
lang C
else
lang en
endif
exe "lang mess" save_messages
exe "lang time" save_time
exe "lang cty" save_ctype

Best regards,
Tony.
--
"Contrariwise," continued Tweedledee, "if it was so, it might be, and
if it were so, it would be; but as it isn't, it ain't. That's logic!"
-- Lewis Carroll, "Through the Looking Glass"

Bram Moolenaar

unread,
Jun 9, 2008, 4:41:25 AM6/9/08
to Bill McCarthy, Vim Developers

Bill McCarthy wrote:

Eh, I think you mean that this doesn't work, and that this is expected.

We don't want to have Vim recognize "1.2" in one environment and "1,2"
in another. "1,2" is not backwards compatible anyway (think of function
arguments, list initializers, etc.) Otherwise Vim scripts would not be
portable.

--
hundred-and-one symptoms of being an internet addict:

19. All of your friends have an @ in their names.

Bill McCarthy

unread,
Jun 9, 2008, 5:45:51 AM6/9/08
to Vim Developers, Bram Moolenaar
On Mon 9-Jun-08 3:41am -0600, Bram Moolenaar wrote:
> Bill McCarthy wrote:

>> Also, commas don't work as expected. Here's what I get
>> from:
>>
>> :echo 1,2
>>
>> 1
>> E15: Invalid expression: ,2
>> E15: Invalid expression: ,2

> Eh, I think you mean that this doesn't work, and that this is expected.

You didn't hear my pause between "work" and "as" :-) Yes,
that should have been written:

"Also, as expected, commas don't work."

--
Best regards,
Bill

Bill McCarthy

unread,
Jun 9, 2008, 5:52:13 AM6/9/08
to Tony Mechelynck, Vim Developers
On Mon 9-Jun-08 2:01am -0600, Tony Mechelynck wrote:
> On 09/06/08 03:43, Bill McCarthy wrote:
>> On Sun 8-Jun-08 4:25pm -0600, Bram Moolenaar wrote:
>>> Bill McCarthy wrote:

>>>> (2) does this LC_NUMERIC actually work on Windows - I recall having
>>>> problems with LC_ALL using the unix sort of GNU
>>>> coreutils - is this an environment variable we need to set?

>>> I haven't tried it. So please set your environment so that a comma is
>>> used for a decimal point and then run Vim to try out the floating point
>>> stuff.

>> The patch applied flawlessly. Both Vim and Gvim makes were
>> without warnings.
>>
>> Without setting any environment variables,all of my tests
>> are working as expected.
>>
>> Also, commas don't work as expected. Here's what I get
>> from:
>>
>> :echo 1,2
>>
>> 1
>> E15: Invalid expression: ,2
>> E15: Invalid expression: ,2
>>
>
> I get the same but I think it's expected -- at least with my locale

Yes, I was trying to say commas don't work <pause> as
expected :-(

Thanks for the explanation. If you know of a way of setting
a locale that accepts commas as decimal points, see if it
causes Vim to accept "1,2" as "1.2" - that's what I think
Bram was asking in his release of the latest floating point
patch.

--
Best regards,
Bill

Tony Mechelynck

unread,
Jun 9, 2008, 6:06:02 AM6/9/08
to vim...@googlegroups.com, Vim Developers
On 09/06/08 11:52, Bill McCarthy wrote:
[...]

> Thanks for the explanation. If you know of a way of setting
> a locale that accepts commas as decimal points, see if it
> causes Vim to accept "1,2" as "1.2" - that's what I think
> Bram was asking in his release of the latest floating point
> patch.
>

I think French normally uses a comma as decimal point, and either a dot
or a space as thousands (and millions etc.) separator. But considering
Bram's latest post, I think Vim is not going to accept 1,2 as being "one
floating point number" regardless of the locale.

Best regards,
Tony.
--
First Law of Procrastination:
Procrastination shortens the job and places the responsibility
for its termination on someone else (i.e., the authority who imposed
the deadline).

John Beckett

unread,
Jun 9, 2008, 7:14:14 AM6/9/08
to vim...@googlegroups.com
Bill McCarthy wrote:
> does this LC_NUMERIC actually work on Windows - I recall
> having problems with LC_ALL using the unix sort of GNU
> coreutils - is this an environment variable we need to set?

Just to spell out the situation: In a country where ',' is used for the decimal
point, a user might have their environment variables set to indicate that fact.
However, Bram decided to have *Vim* override the environment variables so the Vim
process will always use '.' for the decimal point.

You don't have to do anything. Vim configures LC_NUMERIC when running to ensure that
the C library function strtod() works in a consistent way when used in Vim (i.e. Vim
expressions will always interpret "1.23" as a float, and will never interpret "1,23"
as a float).

Bram's suggestion was that those who do use ',' should ensure they have LC_NUMERIC
set so "1,23" is a float in most applications, then confirm that in Vim, it's "1.23"
that is a float, while "1,23" is not.

The previous float patches were using "do-it-yourself" code to convert a string to a
floating point number (which gave rise to the weirdness we discussed last April).
However, Bram has now decided to use strtod() because it handles overflow and
underflow as well as other tricky issues.

Re your comment on 'sort', you probably do want to 'set LC_ALL=C' before running the
GNU sort on Windows.

John

John Beckett

unread,
Jun 9, 2008, 7:14:14 AM6/9/08
to vim...@googlegroups.com
Bram Moolenaar wrote:
> Attached you will find the latest floating point patch.

Thanks Bram. I have patched and compiled without incident. A few tests, and a
superficial look at the code changes, make me believe that the new float patch is
good. As discussed, using strtod() is much more robust.

One query: In file doc/eval.txt we see:
These are INVALID:
1e40 missing .{M}

Perhaps in str2float() help, mention that following IS valid:
str2float('1e40')

John

Dominique Pelle

unread,
Jun 9, 2008, 7:42:37 AM6/9/08
to vim...@googlegroups.com
On Mon, Jun 9, 2008 at 12:06 PM, Tony Mechelynck wrote:

> On 09/06/08 11:52, Bill McCarthy wrote:
> [...]
>> Thanks for the explanation. If you know of a way of setting
>> a locale that accepts commas as decimal points, see if it
>> causes Vim to accept "1,2" as "1.2" - that's what I think
>> Bram was asking in his release of the latest floating point
>> patch.
>>
>
> I think French normally uses a comma as decimal point


Most countries in Europe, use comma rather than dot as
decimal separator. The links below gives the list of countries
that use dot, comma or momayyez as decimal separator (if
that can help testing):

http://en.wikipedia.org/wiki/Decimal_separator#Comma_countries
http://en.wikipedia.org/wiki/Image:DecimalSeparator.png

The thousand separator can also be different with the locale
(space in France, dot in the Netherlands, comma in the UK):

France: 1 234 567,89
Netherlands: 1.234.567,89
UK: 1,234,567.89

-- Dominique

Bram Moolenaar

unread,
Jun 9, 2008, 9:08:00 AM6/9/08
to John Beckett, vim...@googlegroups.com

John Beckett wrote:

Yes, str2float() accepts more than what's in an expression. I'll add a
remark about that.

--
hundred-and-one symptoms of being an internet addict:

25. You believe nothing looks sexier than a man in boxer shorts illuminated
only by a 17" inch svga monitor.

Mikolaj Machowski

unread,
Jun 9, 2008, 1:24:11 PM6/9/08
to vim...@vim.org
Things works, thanks :)

Few things I'd like to see explained (fixed, implemented?):

1. Once a float, always a float. Don't see way to make float other type
of data - string, integer.

2. This is not strictly related to floating point, just noticed:

:echo 1/0
2147483647

:echo 1.0/0
2.147484e+09

Shouldn't divide by 0 throw error?

3. floor(), ceil(), trunc() ?

4. Cosmetic thing but truncating of 0s in floating numbers would be user
friendly (eg. store and display 0.5 instead of 0.500000)

m.

Charles E Campbell Jr

unread,
Jun 9, 2008, 2:55:43 PM6/9/08
to vim...@googlegroups.com
Mikolaj Machowski wrote:
> Things works, thanks :)
>
> Few things I'd like to see explained (fixed, implemented?):
>
> 1. Once a float, always a float. Don't see way to make float other type
> of data - string, integer.
>
At least one can convert floats to strings:

:let x=1.3
:echo type(string(x))

Regards,
Chip Campbell

Bram Moolenaar

unread,
Jun 9, 2008, 3:37:29 PM6/9/08
to Mikolaj Machowski, vim...@vim.org

Mikolaj Machowski wrote:

> Things works, thanks :)
>
> Few things I'd like to see explained (fixed, implemented?):
>
> 1. Once a float, always a float. Don't see way to make float other type
> of data - string, integer.

String -> Float with str2float()
Float -> String with printf()

When would you need Float -> Int? You can actually use
printf(".0f", float), and rely on automatic String to Int conversion,
but it's clumsy.

> 2. This is not strictly related to floating point, just noticed:
>
> :echo 1/0
> 2147483647
>
> :echo 1.0/0
> 2.147484e+09
>
> Shouldn't divide by 0 throw error?

The number you see is the largest int value or a special value for
floats which is INFINITY. It has always worked this way for Ints, don't
know if it is such a good idea to do differently for floats. Although I
would rather get the maximum value, INFINITY doesn't appear to be close
to infinity :-). I suppose I should use MAXFLOAT instead.

> 3. floor(), ceil(), trunc() ?

And round()?



> 4. Cosmetic thing but truncating of 0s in floating numbers would be user
> friendly (eg. store and display 0.5 instead of 0.500000)

I don't see an argument to printf() to get this.

--
For a moment, nothing happened.
Then, after a second or so, nothing continued to happen.
-- Douglas Adams, "The Hitchhiker's Guide to the Galaxy"

Gautam Iyer

unread,
Jun 9, 2008, 4:56:07 PM6/9/08
to vim...@vim.org
On Mon, Jun 09, 2008 at 07:24:11PM +0200, Mikolaj Machowski wrote:

> 2. This is not strictly related to floating point, just noticed:
>
> :echo 1/0
> 2147483647
>
> :echo 1.0/0
> 2.147484e+09
>
> Shouldn't divide by 0 throw error?

The first command (:echo 1/0) gives the same output without the floating
point patch. It's a bug in (regular) Vim.

GI

--
My operat~1 system unders~1 long filena~1 , does yours?

Mikolaj Machowski

unread,
Jun 9, 2008, 5:10:55 PM6/9/08
to vim...@vim.org
Dnia Monday 09 of June 2008, Bram Moolenaar napisał:
> Mikolaj Machowski wrote:
> > Things works, thanks :)
> >
> > Few things I'd like to see explained (fixed, implemented?):
> >
> > 1. Once a float, always a float. Don't see way to make float other
> > type of data - string, integer.
>
> String -> Float with str2float()
> Float -> String with printf()

OK, but...

> When would you need Float -> Int? You can actually use
> printf(".0f", float), and rely on automatic String to Int conversion,
> but it's clumsy.

echo printf("%.0f", "0.4")
E807: expected Float argument for printf()

Also looks like printf() doesn't recognize "real" expression as
argument:

echo printf("%d", "4-2")
4

>
> > 3. floor(), ceil(), trunc() ?
>
> And round()?

Wouldn't hurt ;)

> > 4. Cosmetic thing but truncating of 0s in floating numbers would be
> > user friendly (eg. store and display 0.5 instead of 0.500000)
>
> I don't see an argument to printf() to get this.

To get proper result with printf you have to know precise. To get nice
visually results I have to go through Strings.

m.

John Beckett

unread,
Jun 9, 2008, 7:23:06 PM6/9/08
to vim...@googlegroups.com
Mikolaj Machowski wrote:
> echo printf("%.0f", "0.4")
> E807: expected Float argument for printf()

You mean (argument not a string):
:echo printf("%.0f", 0.4)

> echo printf("%d", "4-2")

Same glitch. It's 4-2 not "4-2".

> user friendly (eg. store and display 0.5 instead of 0.500000)

Here is a workaround:
:let f=1.0/2.0
:echo f
:echo substitute(string(f),'0\+$','','')

John

Ben Schmidt

unread,
Jun 9, 2008, 9:11:07 PM6/9/08
to vim...@googlegroups.com, Mikolaj Machowski
> When would you need Float -> Int? You can actually use
> printf(".0f", float), and rely on automatic String to Int conversion,
> but it's clumsy.

Float -> Int can be very handy, using floats as intermediate
calculations in scripts and then converting to ints for some kind of
display or condition, but usually in combination with a well-defined way
of converting between...i.e. a ceil, floor, round function. It would be
good if some of these could be implemented. How about a single round
function with a second parameter to specify the type of rounding, and
return an int? The second argument could be 'floor|down|int' (round
down), 'ceil|up' (round up), 'trunc|zero' (towards zero), 'away' (away
from zero), 'nearest|round' (towards nearest integer, round away from
zero if half way), 'even' (towards nearest integer, round to the even
number if half way).

>> 2. This is not strictly related to floating point, just noticed:
>>
>> :echo 1/0
>> 2147483647
>>
>> :echo 1.0/0
>> 2.147484e+09
>>
>> Shouldn't divide by 0 throw error?
>
> The number you see is the largest int value or a special value for
> floats which is INFINITY.

Something is wrong there, because it's not anywhere near the largest
value for floats, it is simply the largest value for a 32 bit int
converted to a float. Looks like some integer code has interfered with
the float code. Only on your system though. My system correctly reports
'inf', the special IEEE floating point representation of 'infinity'.

There is still a bug there, though:

:echo -1/0 " gives 2147483647, see below
:echo 0/0 " gives 2147483647, see below
:echo -1.0/0 " gives inf, should give -inf
:echo 0.0/0 " gives inf, should give nan

For the integer ones, the negative should report, if the 'maximum value'
philosophy is followed, -2147483648 (==-2^31, the smallest value a
32-bit int can represent). Though in Vim, a case could be made for
actually returning -2147483647 (i.e. one unit 'too high') since in Vim
-(-2147483648) == -2147483648 due to overflow, which isn't very
desirable! In practice, using -2147483647 and having a sign change work
as expected would be more useful. Care would have to be taken to have
things that work on 64 bit systems, too, I guess (and systems with
smaller words if we still compile for those!). However, this whole idea
isn't all that useful with ints anyway. It is useful with floats,
though, In most environments, integer division by zero chucks an error
and float division reports inf, -inf or nan as appropriate.

Apart from various types rounding, which I can definitely imagine being
useful, are there any mathematical functions that could be handy in a
text processing environment? So far I can only think of 'toy'
applications for them! Perhaps to minimise disruption but allow
flexibility they could all be wrapped in a 'math' function, where the
first argument is the function, and the second and optionally third
arguments are the parameters?

math('sqrt',argument)
math('exp',exponent[,base=e])
math('log',argument[,base=e])
math('sin',argument[,degrees (bool)=0])
math('cos',argument[,degrees (bool)=0])
math('tan',argument[,degrees (bool)=0])
math('atan',argument[,degrees (bool)=0])

I think that covers all the basics in an extensible and inobtrusive way.

>> 4. Cosmetic thing but truncating of 0s in floating numbers would be user
>> friendly (eg. store and display 0.5 instead of 0.500000)
>
> I don't see an argument to printf() to get this.

Yeah, that'd be a good improvement.

Are floats or doubles being used? They are definitely being displayed
with float, not double, precision at present. I would vastly prefer
double precision. 7 significant figures is barely worth it, and wouldn't
cut it for a lot of data files where having floating points in a text
editor would actually be useful! 15 significant figures gives you a lot
of power, and would allow you to interact with the floating points just
as accurately as most other software that would be reading your data
files.

Ben.


Tony Mechelynck

unread,
Jun 9, 2008, 9:27:39 PM6/9/08
to vim...@googlegroups.com, vim...@vim.org
On 09/06/08 19:24, Mikolaj Machowski wrote:
> Things works, thanks :)
>
> Few things I'd like to see explained (fixed, implemented?):
>
> 1. Once a float, always a float. Don't see way to make float other type
> of data - string, integer.
>
> 2. This is not strictly related to floating point, just noticed:
>
> :echo 1/0
> 2147483647

This is documented, about half a page below |expr-/|:

<quote>
When the righthand side of '/' is zero, the result is 0x7fffffff.
</quote>

>
> :echo 1.0/0
> 2.147484e+09

With the new floating point patch, I get "inf" here. Also for ":echo
1/0.0" or any other division by zero except when both operands are integers.

>
> Shouldn't divide by 0 throw error?
>
> 3. floor(), ceil(), trunc() ?
>
> 4. Cosmetic thing but truncating of 0s in floating numbers would be user
> friendly (eg. store and display 0.5 instead of 0.500000)
>
> m.


Best regards,
Tony.
--
Come, every frustum longs to be a cone,
And every vector dreams of matrices.
Hark to the gentle gradient of the breeze:
It whispers of a more ergodic zone.
-- Stanislaw Lem, "Cyberiad"

Gary Johnson

unread,
Jun 9, 2008, 9:37:13 PM6/9/08
to vim...@googlegroups.com
On 2008-06-10, Ben Schmidt <mail_ben...@yahoo.com.au> wrote:

Out of curiosity, why the preference for a few functions with
parameters, e.g.,

> How about a single round function with a second parameter to
> specify the type of rounding, and return an int? The second
> argument could be 'floor|down|int' (round down), 'ceil|up' (round
> up), 'trunc|zero' (towards zero), 'away' (away from zero),
> 'nearest|round' (towards nearest integer, round away from zero if
> half way), 'even' (towards nearest integer, round to the even
> number if half way).

and

> math('sqrt',argument)
> math('exp',exponent[,base=e])
> math('log',argument[,base=e])
> math('sin',argument[,degrees (bool)=0])
> math('cos',argument[,degrees (bool)=0])
> math('tan',argument[,degrees (bool)=0])
> math('atan',argument[,degrees (bool)=0])

rather than several individual functions, e.g.,

floor(argument)
ceil(argument)
abs(argument)
round(argument)
trunc(argument)

and

sqrt(argument
exp(exponent[,base=e])
log(argument[,base=e])
sin(argument[,degrees (bool)=0])
cos(argument[,degrees (bool)=0])
tan(argument[,degrees (bool)=0])
atan(argument[,degrees (bool)=0])

as is more common.

Regards,
Gary

Ben Schmidt

unread,
Jun 9, 2008, 9:45:55 PM6/9/08
to vim...@googlegroups.com

It may also be worth noting that 0.0 and -0.0 are (or should be)
different floats, so, for instance 1/-0.0 should give -inf.

Ben Schmidt

unread,
Jun 9, 2008, 9:56:17 PM6/9/08
to vim...@googlegroups.com
Gary Johnson wrote:
> On 2008-06-10, Ben Schmidt <mail_ben...@yahoo.com.au> wrote:
>
> Out of curiosity, why the preference for a few functions with
> parameters, e.g.,

To be honest, I probably prefer the 'many functions' approach. I was
just thinking in terms of not cluttering the Vim function namespace with
functions for a feature that isn't really core to a text editor.

Though for the rounding, there are so many different types and different
names for the different types, that I thought a single function to group
them together made sense.

Still, the chances of an actual name clash are small--if we called a
function by one of those names with a different purpose, it would cause
plenty of confusion, and I guess just another section of :help
function-list is needed.

> abs(argument)

That's a good thought. Vim should have that one, for ints and floats.
sgn() wouldn't go astray either.

Another that could conceivably be useful would be a random number
function. A low quality PRNG would do just fine. This could be used in
Vim for editing data files for testing purposes, etc.

Ben.

John Beckett

unread,
Jun 9, 2008, 11:55:04 PM6/9/08
to vim...@googlegroups.com
Ben Schmidt wrote:
> math('sqrt',argument)
> math('exp',exponent[,base=e])
> math('log',argument[,base=e])
> math('sin',argument[,degrees (bool)=0])
> math('cos',argument[,degrees (bool)=0])
> math('tan',argument[,degrees (bool)=0])
> math('atan',argument[,degrees (bool)=0])

Considering the functions, not the syntax to call them, I would have to suggest that
it would be better to use Python-in-Vim for this sort of thing (and get complex
numbers as well, plus heaps more).

For example:
http://vim.wikia.com/wiki/Scientific_calculator

Someone might like to consider how moving Vim float variables into Python, and
getting float results back, works.

It would be a pointless waste of development time to do much more with floats in
Vim, IMHO.

> Are floats or doubles being used? They are definitely being
> displayed with float, not double, precision at present.

Vim's float code is using doubles.

I haven't done anything serious with floats for years, but my vague recollection is
that you would have to use something like printf('%.20f',myfloat) to see lots of
precision (i.e. I think what you are seeing in Vim is just standard behaviour).

John

Gautam Iyer

unread,
Jun 10, 2008, 12:04:19 AM6/10/08
to vim...@googlegroups.com
On Tue, Jun 10, 2008 at 01:55:04PM +1000, John Beckett wrote:

> It would be a pointless waste of development time to do much more with
> floats in Vim, IMHO.

I *strongly* agree! Apart from the basic operations, the rest can be
left to vim-perl/python/ruby/etc. Please don't bloat Vim.

GI

--
'Impatience' -- Waiting in a hurry.

Ben Schmidt

unread,
Jun 10, 2008, 12:29:58 AM6/10/08
to vim...@googlegroups.com
John Beckett wrote:
> Ben Schmidt wrote:
>> math('sqrt',argument)
>> math('exp',exponent[,base=e])
>> math('log',argument[,base=e])
>> math('sin',argument[,degrees (bool)=0])
>> math('cos',argument[,degrees (bool)=0])
>> math('tan',argument[,degrees (bool)=0])
>> math('atan',argument[,degrees (bool)=0])
>
> Considering the functions, not the syntax to call them, I would have
> to suggest that it would be better to use Python-in-Vim for this sort
> of thing (and get complex numbers as well, plus heaps more).

You can leverage that argument about the entire floating point patch.

That said, the only functions I can imagine being truly useful in a text
editing setting, as opposed to an application that truly does require
something more numerically oriented, like a scripting language or
spreadsheet, are:

- rounding functions
- absolute value function
- sign function
- random number function
- power function (either exp() with variable base or pow() with
arguments in the reverse order)

Not the rest of the mathematical functions, the majority of which you
noted above. As I said, I can only think of 'toy' applications for them.

> It would be a pointless waste of development time to do much more with
> floats in Vim, IMHO.

Despite my comments above, I don't think writing a wrapper around a C
library function is long or hard work, which is basically all this
requires. If you're going to do one or two, which I think could be very
useful, you might as well do all ten while you're at it. Saves having to
do it later when someone discovers they need it!

But that said, yes, there are other Vim features I would much rather see
than this: variable tab stops, for instance, which are useful for many
more (most tab separated) data files than floating point computation is.

>> Are floats or doubles being used? They are definitely being
>> displayed with float, not double, precision at present.
>
> Vim's float code is using doubles.
>
> I haven't done anything serious with floats for years, but my vague
> recollection is that you would have to use something like
> printf('%.20f',myfloat) to see lots of precision (i.e. I think what
> you are seeing in Vim is just standard behaviour).

Yes, this works (well, 20 doesn't work, because they don't have that
much precision, so it just prints additional rubbish digits, but that is
as expected)!

Ben.

Mikołaj Machowski

unread,
Jun 10, 2008, 2:37:48 AM6/10/08
to vim_dev
Dnia 10-06-2008 o godz. 6:04 Gautam Iyer napisał(a):
> On Tue, Jun 10, 2008 at 01:55:04PM +1000, John Beckett wrote:
>
> > It would be a pointless waste of development time to do much more with
> > floats in Vim, IMHO.
>
> I *strongly* agree! Apart from the basic operations, the rest can be
> left to vim-perl/python/ruby/etc. Please don't bloat Vim.

Strongly agree too. Asked for floor/ceil/trunc/round as *strictly*
related to floating point operations, introduction of the rest is waste
of precious developer time.

m.

ps. Personally could use sqrt(), I need that surprisingly often :)

----------------------------------------------------
Poznaj kitesurfing i zobacz najlepszych w akcji.
Puchar Polski w kitesurfingu już od 13 czerwca w Rewie.
Sprawdź sam: http://klik.wp.pl/?adr=http%3A%2F%2Fcorto.www.wp.pl%2Fas%2Fextrema9960815.html&sid=382


Charles E Campbell Jr

unread,
Jun 10, 2008, 8:58:45 AM6/10/08
to vim...@googlegroups.com
Ben Schmidt wrote:
>
> Another that could conceivably be useful would be a random number
> function. A low quality PRNG would do just fine. This could be used in
> Vim for editing data files for testing purposes, etc.
>

Not that I object to a built-in PRNG to vim; however, writing a plugin
to do it wasn't that difficult. I've provided Rndm.vim (available at my
website) and Rndm.vim also accompanies Mines.vim
(http://vim.sourceforge.net/scripts/script.php?script_id=551) if you're
interested.

Of course, Abs() and Sgn() are even easier...

Regards,
Chip Campbell

Charles E Campbell Jr

unread,
Jun 10, 2008, 9:09:38 AM6/10/08
to vim...@googlegroups.com
Mikołaj Machowski wrote:
> Dnia 10-06-2008 o godz. 6:04 Gautam Iyer napisał(a):
>
>> On Tue, Jun 10, 2008 at 01:55:04PM +1000, John Beckett wrote:
>>
>>
>>> It would be a pointless waste of development time to do much more with
>>> floats in Vim, IMHO.
>>>
>> I *strongly* agree! Apart from the basic operations, the rest can be
>> left to vim-perl/python/ruby/etc. Please don't bloat Vim.
>>
>
> Strongly agree too. Asked for floor/ceil/trunc/round as *strictly*
> related to floating point operations, introduction of the rest is waste
> of precious developer time.
>
And, for variety -- I strongly disagree!

"Maintaining" floating point functions such as sin(), cos(), etc --
well, those are extremely simple function calls to make to library
functions that compilers already provide, so it wouldn't surprise me if
they were written-once-never-touched-again functions. Extra size would
come from the often dynamically loaded shared libraries -- ie. providing
such functions would only barely increase the size of vim (although they
could increase the runtime image size, but only if the functions were
actually invoked).

Whereas, requiring a vim to include the interfaces to
python/ruby/pick-your-poison ... well, now you're talking real bloat (as
in increasing the vim executable size).

Regards,
Chip Campbell

Tony Mechelynck

unread,
Jun 10, 2008, 9:51:54 AM6/10/08
to vim...@googlegroups.com
On 10/06/08 15:09, Charles E Campbell Jr wrote:
[...]

> Whereas, requiring a vim to include the interfaces to
> python/ruby/pick-your-poison ... well, now you're talking real bloat (as
> in increasing the vim executable size).
>
> Regards,
> Chip Campbell

Well, like you I think, I believe that vim-script is usually quite
enough for most of the things one would want to do with Vim; but I have
seen people who apparently cannot think of programming Vim in other than
Perl or Python (etc.). As I think you know, for people who think of such
interfaces as "useless bloat", they can be excluded bodily at
compile-time, and compiling Vim is not really difficult. The only bloat
then would be in sources which are left out of the executable, either
because the modules in question are simply not compiled, or because, in
included modules, the instructions in question are in the false branch
of some #ifdef; and I believe that such "source-only bloat" can be
tolerated.

Best regards,
Tony.
--
If you want your spouse to listen and pay strict attention to every
word you say, talk in your sleep.

Charles E Campbell Jr

unread,
Jun 10, 2008, 10:34:07 AM6/10/08
to vim...@googlegroups.com
Tony Mechelynck wrote:
> On 10/06/08 15:09, Charles E Campbell Jr wrote:
> [...]
>
>> Whereas, requiring a vim to include the interfaces to
>> python/ruby/pick-your-poison ... well, now you're talking real bloat (as
>> in increasing the vim executable size).
>>
>> Regards,
>> Chip Campbell
>>
>
> Well, like you I think, I believe that vim-script is usually quite
> enough for most of the things one would want to do with Vim; but I have
> seen people who apparently cannot think of programming Vim in other than
> Perl or Python (etc.). As I think you know, for people who think of such
> interfaces as "useless bloat", they can be excluded bodily at
> compile-time, and compiling Vim is not really difficult. The only bloat
> then would be in sources which are left out of the executable, either
> because the modules in question are simply not compiled, or because, in
> included modules, the instructions in question are in the false branch
> of some #ifdef; and I believe that such "source-only bloat" can be
> tolerated.
>
I agree that vim-script is usually "quite enough...", and I understand
that there are those who prefer Perl/Python/etc. I probably misstated
my point, which I intended to be that worrying about the few extra lines
of source to support sin()/cos()/etc in vim is misplaced -- maintenance
would be nearly non-existent, the interface code would be tiny, runtime
image size would likely be affected only if the functions were invoked,
and that the counter-proposal to "just use python" involves considerably
more bytes in the runtime image -- without invoking python. Plus a lot
of trouble for anyone who doesn't happen to have python compiled for
their system or perhaps doesn't know how to compile python support into
vim (or whichever external program is proposed: perl, ruby, ...). I
myself happen to have both python and perl on my linux boxes plus
generally have perl support compiled into my vim executable, so this
isn't a difficulty I'd have myself.

Now, the contention that a text editor just shouldn't have
sin()/cos()/floating-point support; that's a different matter.
Personally, I think it depends on what an individual wants to do. For
example, consider someone who wishes to present coordinates in both
rectangular and polar forms. Perhaps someone would like to do some
fancy textwork and have it justified inside some mathematically defined
shape (cirles/ellipses) -- maybe even provide a plugin to do such. I
know that in the case of circles/ellipses one could likely do something
with the Bresenham integer-only algorithm (I've provided a
circle/ellipse drawing tool with DrawIt), but that requires knowledge
about that type of algorithm. Perhaps one would like to provide a small
spreadsheet capability in vim, to crosscheck or spot-check output to a
file...

Bram has already mentioned ease of doing something with columns of numbers.

However, I'd agree that there shouldn't be any effort devoted to
supporting "special" math functions in vim (ie. Bessel functions,
parabolic cylinder functions, elliptical functions, ...) -- just the
small interfaces to those functions that come with most compilers (trig,
log, exponential).

And, as an off-subject item: I'd really like to have Vince Negri's
conceal/ownsyntax patch incorporated! Working with LaTeX would be so
much better...

Tony Mechelynck

unread,
Jun 10, 2008, 11:38:06 AM6/10/08
to vim...@googlegroups.com
On 10/06/08 16:34, Charles E Campbell Jr wrote:
[...]
> Now, the contention that a text editor just shouldn't have
> sin()/cos()/floating-point support; that's a different matter.
> Personally, I think it depends on what an individual wants to do. For
> example, consider someone who wishes to present coordinates in both
> rectangular and polar forms. Perhaps someone would like to do some
> fancy textwork and have it justified inside some mathematically defined
> shape (cirles/ellipses) -- maybe even provide a plugin to do such. I
> know that in the case of circles/ellipses one could likely do something
> with the Bresenham integer-only algorithm (I've provided a
> circle/ellipse drawing tool with DrawIt), but that requires knowledge
> about that type of algorithm. Perhaps one would like to provide a small
> spreadsheet capability in vim, to crosscheck or spot-check output to a
> file...

Or, with SVG graphics (which are actually a sort of text format, maybe
barely human-readable) becoming more and more common, you might need
trigonometric functions to check, at least approximately, how much space
some slanted line -- possibly some slanted line of text -- would need.

>
> Bram has already mentioned ease of doing something with columns of numbers.

Yes, and for very long files, one might perhaps want an additional digit
or two in the "percentage" item of the status line.

>
> However, I'd agree that there shouldn't be any effort devoted to
> supporting "special" math functions in vim (ie. Bessel functions,
> parabolic cylinder functions, elliptical functions, ...) -- just the
> small interfaces to those functions that come with most compilers (trig,
> log, exponential).

The more complex the functions, the fewer people can be expected to know
how to use them anyway. Trig, log and exponential are at high-school
level, or at least they were when I was in high school (latin-math
section) forty years ago. I wouldn't expect anyone below college level
to even know what Bessel etc. are really for, even if they've heard the
name, which is already far from certain.

>
> And, as an off-subject item: I'd really like to have Vince Negri's
> conceal/ownsyntax patch incorporated! Working with LaTeX would be so
> much better...

Even "fancy display" of HTML -- switch from "source" display to
"rendering" display by hitting a (mapped) key.

Here though, instead of Vince's patch one could send the text to a
browser, maybe a console-mode one such as Lynx displaying in Vim's (not
gvim's) own console, or else something like ":exe '!seamonkey -url
file:///' . expand('%:p')" or similar (for full generality one would
need to percent-escape spaces and other "special" characters), making
use of the fact that Mozilla browsers will by default use something very
much akin to Vim's client-server facility, passing the URL to an
already-running instance if there is one.


Best regards,
Tony.
--
"If dolphins are so smart, why did Flipper work for television?"

Christian J. Robinson

unread,
Jun 8, 2008, 2:40:33 PM6/8/08
to vim...@googlegroups.com
On Sun, 8 Jun 2008, Bram Moolenaar wrote:

> Please check if this works correctly:
>
> echo 0.9999999999999999999999999999999999
>
> The result should be "1.000000".

Works fine for me. (RedHat based Linux system.)

> Let's give this some testing.

So far the only issue I encountered was a warning when Vim loaded the
NERD_commenter plugin:

Error detected while processing ~/.vim/plugin/NERD_commenter.vim:
line 4:
E806: using Float as a String
E15: Invalid expression: 2.1.11

The offending line being:

let s:NERD_commenter_version = 2.1.11

This variable isn't used anywhere in the script, and I can't imagine a
version string of "2111" being all that useful (or reliable for any
kind of version checking matching). I simply added quotes around it
and everything was fine.

I found another plugin written by the same author (NERD_tree) and
examined it, and it has the following line, unmodified:

let s:NERD_tree_version = '2.9.0'

So I don't this error should be counted against the latest
implementation of floating point patch.

> If there are no serious problems I plan to add this in Vim 7.2
> (whenever that is ready).

Perhaps when this year's GSoC is done?

- Christian

--
Support FREE software. Write it yourself.
Christian J. Robinson <infy...@onewest.net> -- http://infynity.spodzone.com/

Bram Moolenaar

unread,
Jun 10, 2008, 3:02:43 PM6/10/08
to Ben Schmidt, vim...@googlegroups.com, Mikolaj Machowski

Ben Schmidt wrote:

> > When would you need Float -> Int? You can actually use
> > printf(".0f", float), and rely on automatic String to Int conversion,
> > but it's clumsy.
>
> Float -> Int can be very handy, using floats as intermediate
> calculations in scripts and then converting to ints for some kind of
> display or condition, but usually in combination with a well-defined way
> of converting between...i.e. a ceil, floor, round function. It would be
> good if some of these could be implemented. How about a single round
> function with a second parameter to specify the type of rounding, and
> return an int? The second argument could be 'floor|down|int' (round
> down), 'ceil|up' (round up), 'trunc|zero' (towards zero), 'away' (away
> from zero), 'nearest|round' (towards nearest integer, round away from
> zero if half way), 'even' (towards nearest integer, round to the even
> number if half way).

Please, please don't start thinking of all kinds of things we can add to
Vim. There is no end to it. And for every feature one can come up with
there is always someone who can think of a use for it.

The use of adding floating point support is discutable anyway. I think
just adding basic operations, which are very likely needed once you have
floating point numbers, is all we should do at this point.

For example, round() can convert a float to an int. It makes sense to
add that: after using floating point computations to avoid roundoff
problems you want the resulting number (e.g., a percentage).

I think we don't really need the others:
floor(f) == round(f - 0.5)
ceil(f) == round(f + 0.49999)
trunc(f) == f > 0.0 ? round(f - 0.5) : round(f + 0.5)

I can't remember ever needing trunc(), I find it acceptable it's a bit
complicated.


> >> 2. This is not strictly related to floating point, just noticed:
> >>
> >> :echo 1/0
> >> 2147483647
> >>
> >> :echo 1.0/0
> >> 2.147484e+09
> >>
> >> Shouldn't divide by 0 throw error?
> >
> > The number you see is the largest int value or a special value for
> > floats which is INFINITY.
>
> Something is wrong there, because it's not anywhere near the largest
> value for floats, it is simply the largest value for a 32 bit int
> converted to a float. Looks like some integer code has interfered with
> the float code. Only on your system though. My system correctly reports
> 'inf', the special IEEE floating point representation of 'infinity'.

It looks like a problem with the FreeBSD include files.

> There is still a bug there, though:
>
> :echo -1/0 " gives 2147483647, see below
> :echo 0/0 " gives 2147483647, see below

This is as specified. It's better than crashing, don't expect a valid
result.

> :echo -1.0/0 " gives inf, should give -inf
> :echo 0.0/0 " gives inf, should give nan

The "inf" and "nan" values are not defined for Vim.

I really think we can do without most of these. Vim is not a
mathematical calculator. One that can be useful is log10(f), since it
gives an indication of the length of the number/float converted to a
string. Although you could do it with len(printf('%f', f)).

> >> 4. Cosmetic thing but truncating of 0s in floating numbers would be user
> >> friendly (eg. store and display 0.5 instead of 0.500000)
> >
> > I don't see an argument to printf() to get this.
>
> Yeah, that'd be a good improvement.

I mean: Vim is using the library printf() to do the conversion, but I
don't see a way to tell printf() to omit superfluous zeroes.

> Are floats or doubles being used? They are definitely being displayed
> with float, not double, precision at present. I would vastly prefer
> double precision. 7 significant figures is barely worth it, and wouldn't
> cut it for a lot of data files where having floating points in a text
> editor would actually be useful! 15 significant figures gives you a lot
> of power, and would allow you to interact with the floating points just
> as accurately as most other software that would be reading your data
> files.

Double is used, as floats are often converted to double anyway when
using math functions and operators.

--
How To Keep A Healthy Level Of Insanity:
2. Page yourself over the intercom. Don't disguise your voice.

Gautam Iyer

unread,
Jun 10, 2008, 3:37:57 PM6/10/08
to vim...@googlegroups.com
On Tue, Jun 10, 2008 at 09:09:38AM -0400, Charles E Campbell Jr wrote:

> Whereas, requiring a vim to include the interfaces to
> python/ruby/pick-your-poison ... well, now you're talking real bloat
> (as in increasing the vim executable size).

Not really! I never compile those in anyway :). Maybe I could not
compile in floating point stuff, and stop grumbling about functions like
sin() in a text editor...

GI

--
Dijon vu: The same mustard as before.

Tony Mechelynck

unread,
Jun 10, 2008, 4:12:20 PM6/10/08
to vim...@googlegroups.com, Ben Schmidt, Bram Moolenaar
On 10/06/08 21:02, Bram Moolenaar wrote:
>
> Ben Schmidt wrote:
[...]

>>>> 4. Cosmetic thing but truncating of 0s in floating numbers would be user
>>>> friendly (eg. store and display 0.5 instead of 0.500000)
>>> I don't see an argument to printf() to get this.
>> Yeah, that'd be a good improvement.
>
> I mean: Vim is using the library printf() to do the conversion, but I
> don't see a way to tell printf() to omit superfluous zeroes.
[...]

It can be done easily (well, sort of) in vim-script post-processing:

function FloatToStr(f)
let retval = printf('%g', a:f)
if retval == '0.000000e+00' " special case
let retval = '0.0'
elseif retval == '-0.000000e+00' " another special case
let retval = '-0.0'
elseif retval =~ 'e\|[^0]$' " exponent or no trailing zeroes
" do nothing
else
" remove trailing zeroes
let retval = retval[:match(retval, '0*$') - 1]
" but leave at least one digit after the decimal point
if retval =~ '\.$'
let retval .= '0'
endif
endif
return retval
endfunction

Best regards,
Tony.

Tony Mechelynck

unread,
Jun 10, 2008, 4:14:49 PM6/10/08
to Gautam Iyer, vim...@googlegroups.com

Anyway it isn't yet part of the standard sources: at the latest news,
you can postpose your decision till 7.2 comes along.

Best regards,
Tony.
--
"The sooner you fall behind, the more time you'll have to catch up!"

John Beckett

unread,
Jun 10, 2008, 7:54:03 PM6/10/08
to vim...@googlegroups.com
Bram Moolenaar wrote:
> I mean: Vim is using the library printf() to do the
> conversion, but I don't see a way to tell printf() to omit
> superfluous zeroes.

g and G omit superfluos zeroes, as well as the decimal point:

double n = 12;
printf("%g\n", n); // prints 12
printf("%#g\n", n); // prints 12.0000

John

Bill McCarthy

unread,
Jun 10, 2008, 11:54:31 PM6/10/08
to Vim Developers, Bram Moolenaar
On Tue 10-Jun-08 2:02pm -0600, Bram Moolenaar wrote:

> I think just adding basic operations, which are very likely needed
> once you have floating point numbers, is all we should do at this
> point.
>
> For example, round() can convert a float to an int. It makes sense
> to add that: after using floating point computations to avoid
> roundoff problems you want the resulting number (e.g., a
> percentage).

Once you write something for 'double func(double)', you've got:

sin, cos, tan, sinh, cosh, tanh, asin, acos,
atan, exp, log, log10, sqrt, ceil, floor, fabs

And once you do 'double func(double, double)', then you have:

atan2, pow, fmod

These are all readily available when you compile with <math.h>.

Although I'd love to see an operator to raise a number to a power,
that would appear far more complicated that just providing pow().

Personally, I can do without the trig and rounding stuff, but find
exp(), log() and pow() to be essential. OTOH, adding the other
functions is almost completely cost free.

--
Best regards,
Bill

Ben Schmidt

unread,
Jun 11, 2008, 1:15:15 AM6/11/08
to Bram Moolenaar, vim...@googlegroups.com, Mikolaj Machowski
Bram Moolenaar wrote:
> Ben Schmidt wrote:
>
>>> When would you need Float -> Int? You can actually use
>>> printf(".0f", float), and rely on automatic String to Int conversion,
>>> but it's clumsy.
>> Float -> Int can be very handy, using floats as intermediate
>> calculations in scripts and then converting to ints for some kind of
>> display or condition, but usually in combination with a well-defined way
>> of converting between...i.e. a ceil, floor, round function. It would be
>> good if some of these could be implemented. How about a single round
>> function with a second parameter to specify the type of rounding, and
>> return an int? The second argument could be 'floor|down|int' (round
>> down), 'ceil|up' (round up), 'trunc|zero' (towards zero), 'away' (away
>> from zero), 'nearest|round' (towards nearest integer, round away from
>> zero if half way), 'even' (towards nearest integer, round to the even
>> number if half way).
>
> Please, please don't start thinking of all kinds of things we can add to
> Vim. There is no end to it. And for every feature one can come up with
> there is always someone who can think of a use for it.
>
> The use of adding floating point support is discutable anyway. I think
> just adding basic operations, which are very likely needed once you have
> floating point numbers, is all we should do at this point.

I don't think this is a case of 'all kinds of things'. These are
standard bread and butter functions that are used when dealing with
floating points. They are not specialised mathematical functions, they
are simple, useful and important arithmetic functions. When the 'list'
and 'dictionary' datatypes were added, each came with a dozen or more
functions to work with them and make them truly useful. Floats, too, can
be made truly useful by having some functions to work with them, as in
every other language I can think of that uses that data type. I was
endeavouring to keep this to a minimum by suggesting merely two
functions which could be easily extended in future if needs arose.

I'm afraid I'm of the school of thought that says, "if you're going to
do it, do it properly." I realise this kinda clashes with your
philosophy for Vim (indeed, it's about the only thing I find really
frustrating about Vim), but I still think it's a good idea, and these
functions would be truly useful in many simple data processing
applications that are suitable for performing in a text editor. Having
floats that are crippled or, worse, inaccurate, is worse than not having
them at all, IM(NS)HO.

> For example, round() can convert a float to an int. It makes sense to
> add that: after using floating point computations to avoid roundoff
> problems you want the resulting number (e.g., a percentage).
>
> I think we don't really need the others:
> floor(f) == round(f - 0.5)
> ceil(f) == round(f + 0.49999)

Are you implying you expect the user to figure out how to represent in
decimal the number that is one bit lower than 0.5 in floating point
representation? Obviously 0.49999 is not actually the number required
here, but that one. Also, whether these would work depends on the
specifics of round() which haven't been specified: which way does 0.5
round? 1.5? Negatives of the same? Etc. To avoid accumulation of errors,
a round-to-even strategy is usually employed, but this is not always
what the user desires, and would result in strange results for the
above. This is such a can of worms, with arguments so many ways for
different approaches, and with good reason, and with different
conventions being taught in different countries and different courses,
and it is precisely because of this, and to avoid ambiguity, I think it
would be best for Vim to offer the different types of rounding (my
suggestion is to do so by 'overloading' a round() function), clearly
defining what each does.

> trunc(f) == f > 0.0 ? round(f - 0.5) : round(f + 0.5)
>
> I can't remember ever needing trunc(), I find it acceptable it's a bit
> complicated.

Well, trunc() is essentially what happens if you do an integer division,
so it's a fairly common case, e.g. if finding a fractional remainder or
such. Indeed, I believe it's more commonly needed than ceil or floor,
but harder to implement, and so most settle for one of the others,
particularly since they often are dealing only with positive numbers.
But negative numbers are useful, too. :-)

>>>> 2. This is not strictly related to floating point, just noticed:
>>>>
>>>> :echo 1/0
>>>> 2147483647
>>>>
>>>> :echo 1.0/0
>>>> 2.147484e+09
>>>>
>>>> Shouldn't divide by 0 throw error?
>>> The number you see is the largest int value or a special value for
>>> floats which is INFINITY.
>> Something is wrong there, because it's not anywhere near the largest
>> value for floats, it is simply the largest value for a 32 bit int
>> converted to a float. Looks like some integer code has interfered with
>> the float code. Only on your system though. My system correctly reports
>> 'inf', the special IEEE floating point representation of 'infinity'.
>
> It looks like a problem with the FreeBSD include files.

What a nuisance.

>> There is still a bug there, though:
>>
>> :echo -1/0 " gives 2147483647, see below
>> :echo 0/0 " gives 2147483647, see below
>
> This is as specified. It's better than crashing, don't expect a valid
> result.
>
>> :echo -1.0/0 " gives inf, should give -inf
>> :echo 0.0/0 " gives inf, should give nan
>
> The "inf" and "nan" values are not defined for Vim.

"If a program is useful, it will have to be changed. If a program is
useless, it will have to be documented."

I hate this approach. :-)

Vim currently reports 'inf' for -1.0/0, which is undeniably wrong
mathematically. Ditto for -1/0 for which it returns 2147483647. You
could argue that number is a good approximation for 1/0, but not for
-1/0 or 0/0. Better than crashing perhaps, but I reckon an error would
be better than either of the other alternatives. Or at least return
'nan' for all the float ones, not 'inf'. It surely can't happen very
often, but it's these sorts of mindless subtleties that waste hours of
time tracking down when you write a script and it just doesn't work as
you expect despite seeming support from the underlying software. It
works in your simple test case, so you write a script based on that
support, only to find it breaks later because it only looks like it's
supported in a common case.

What's more, this stuff can be operated on, and works, presumably
because it falls back to underlying floating point arithmetic of the
processor, rather than getting intercepted by Vim: (1.0/0) / (1.0/0)
gives nan as expected. -(1.0/0) gives -inf as expected. That -(1.0/0)
and -1.0/0 give results that are infinitely different is a bug in my
eyes.

In my "do it properly" philosophy, this stuff should either fully work,
or not work at all, i.e. give errors. It should not give inconsistent
and mathematically wrong results. And documenting it doesn't make it any
better, IMHO.

My preference is to make it fully work.

I can certainly understand leaving the integers as is, for
compatibility, though would suggest this is something that should be
considered for changing in a future compatibility-breaking update. I
would prefer an error to be thrown on division by zero, or at least to
have that as an option; having -1/0 and 0/0 give essentially positive
infinity is most certainly wrong, even if it's documented. Thrown errors
are better than silently wrong answers. And an error could always be
:silen!ced.

>> math('sqrt',argument)
>> math('exp',exponent[,base=e])
>> math('log',argument[,base=e])
>> math('sin',argument[,degrees (bool)=0])
>> math('cos',argument[,degrees (bool)=0])
>> math('tan',argument[,degrees (bool)=0])
>> math('atan',argument[,degrees (bool)=0])
>>
>> I think that covers all the basics in an extensible and inobtrusive way.
>
> I really think we can do without most of these. Vim is not a
> mathematical calculator. One that can be useful is log10(f), since it
> gives an indication of the length of the number/float converted to a
> string. Although you could do it with len(printf('%f', f)).

As per my other email, a power function would be good. It could be used
for square roots, too, of course.

Random number generation would also be good, though as Chip pointed out,
this can easily be done with a script. (This is in contrast to a power
function and the rounding functions. Ditto with abs() and sgn() and
factorial, which I didn't mention before precisely because it's easily
scriptable.)

I wouldn't be all that sad to lose the other mathematical functions,
though I must say that I certainly would find it tremendously useful to
have that functionality available natively in my text editor. From
deciding coordinates to hard code for GUI items, to calculating integer
values to use for sound levels, to doing a little algorithmic analysis
to see whether time spent implementing a more efficient algorithm would
be necessary or worthwhile. I do quite a bit of this kind of stuff, and
at the moment have to open a terminal window, do my work, and copy and
paste the results around. It would be heaps easier if I just had to deal
with Vim. It's not like I'm struggling to find applications: I use bc
every couple of days, using only its simple log, sin, cos and atan
functions and copy and paste my results into Vim. It would truly be
useful...for me.

> I mean: Vim is using the library printf() to do the conversion, but I
> don't see a way to tell printf() to omit superfluous zeroes.

O, right. I don't know of a way to do this either.

>> Are floats or doubles being used? They are definitely being displayed
>> with float, not double, precision at present. I would vastly prefer
>> double precision. 7 significant figures is barely worth it, and wouldn't
>> cut it for a lot of data files where having floating points in a text
>> editor would actually be useful! 15 significant figures gives you a lot
>> of power, and would allow you to interact with the floating points just
>> as accurately as most other software that would be reading your data
>> files.
>
> Double is used, as floats are often converted to double anyway when
> using math functions and operators.

That's good.

Ben.

Milan Vancura

unread,
Jun 11, 2008, 7:24:42 AM6/11/08
to vim...@googlegroups.com
> Here though, instead of Vince's patch one could send the text to a
> browser, maybe a console-mode one such as Lynx displaying in Vim's (not
> gvim's) own console, or else something like ":exe '!seamonkey -url
> file:///' . expand('%:p')" or similar (for full generality one would
> need to percent-escape spaces and other "special" characters), making
> use of the fact that Mozilla browsers will by default use something very
> much akin to Vim's client-server facility, passing the URL to an
> already-running instance if there is one.

http://www.w3schools.com/css/tryit.asp?filename=trycss_text-decoration

plus "It's All Text" extension to forefox...

similar for a column of numbers: use sc which has plenty of functions...

Milan
--
Milan Vancura, Prague, Czech Republic, Europe

Bram Moolenaar

unread,
Jun 11, 2008, 5:23:43 PM6/11/08
to John Beckett, vim...@googlegroups.com

John Beckett wrote:

Vim is already using %g. For me the results are different.

--
How To Keep A Healthy Level Of Insanity:

6. In the memo field of all your checks, write "for sexual favors".

George V. Reilly

unread,
Jun 11, 2008, 6:38:39 PM6/11/08
to vim...@googlegroups.com, Bram Moolenaar, Mikolaj Machowski
I haven't been following this long thread too closely, but it seems to me that the right way to do this is for Vim to delegate floating-point handling to the underlying C implementation of double arithmetic as much as possible, and to wrap the usual set of FP functions. As far as I can tell, this is what almost all other languages do nowadays. It certainly would give fewer surprises to get NaN for division by 0.0 than 0x7FFFFFFF.

The canonical reference for floating point seems to be Goldberg's "What Every Computer Scientist Should Know About Floating-Point Arithmetic", http://docs.sun.com/source/806-3568/ncg_goldberg.html. I should re-read it myself; it's been years.
--
/George V. Reilly geo...@reilly.org
http://www.georgevreilly.com/blog http://blogs.cozi.com/tech

John Beckett

unread,
Jun 11, 2008, 7:50:39 PM6/11/08
to Br...@moolenaar.net, vim...@googlegroups.com
Bram Moolenaar wrote:
>> g and G omit superfluos zeroes, as well as the decimal point:
>>
>> double n = 12;
>> printf("%g\n", n); // prints 12
>> printf("%#g\n", n); // prints 12.0000
>
> Vim is already using %g. For me the results are different.

In Vim, the code in vim_snprintf() (in message.c) replaces 'g' with 'f' for a small
value like 12, so Vim does not give the result quoted above. However, "standard"
printf should do what I said (see [1]).

I am one of those who are inclined to NOT complicate the Vim source by attending to
details of handling floating point, so I would live with the current situation.
However, it did occur to me that you might contemplate whether a config build option
could specify if the native snprintf() should be used. Then if someone wants
"standard" printf, they could build Vim so vim_snprintf() calls the version supplied
by their library.

Or, the code in vim_snprintf() could be made a little more complex by NOT replacing
'g' with 'f'. I'll have a go at that if you like (needs a little care to be sure we
won't overflow the tmp buffer).

[1] I have confirmed my claim quoted above on two current systems: Windows + Linux.
There are also lots of references that confirm this (including a BSD manual). In
http://en.wikipedia.org/wiki/Printf the description for g,G says:

"Print a double in either normal or exponential notation, whichever is more
appropriate for its magnitude. 'g' uses lower-case letters, 'G' uses upper-case
letters. This type differs slightly from fixed-point notation in that insignificant
zeroes to the right of the decimal point are not included. Also, the decimal point
is not included on whole numbers."

John

Bram Moolenaar

unread,
Jun 12, 2008, 11:00:48 AM6/12/08
to John Beckett, vim...@googlegroups.com

John Beckett wrote:

> Bram Moolenaar wrote:
> >> g and G omit superfluos zeroes, as well as the decimal point:
> >>
> >> double n = 12;
> >> printf("%g\n", n); // prints 12
> >> printf("%#g\n", n); // prints 12.0000
> >
> > Vim is already using %g. For me the results are different.
>
> In Vim, the code in vim_snprintf() (in message.c) replaces 'g' with
> 'f' for a small value like 12, so Vim does not give the result quoted
> above. However, "standard" printf should do what I said (see [1]).

I forgot about that. I'll have to look into it again.

> I am one of those who are inclined to NOT complicate the Vim source by
> attending to details of handling floating point, so I would live with
> the current situation. However, it did occur to me that you might
> contemplate whether a config build option could specify if the native
> snprintf() should be used. Then if someone wants "standard" printf,
> they could build Vim so vim_snprintf() calls the version supplied by
> their library.

We can't use the native snprintf() directly, because it may crash Vim.
Instead we use a wrapper, but still rely on the library .*printf
functions to do the actual Float to String conversion.

I also want to minimize configure options, because the behavior should
be predictable. Esp. for binaries included with a distribution.

> Or, the code in vim_snprintf() could be made a little more complex by
> NOT replacing 'g' with 'f'. I'll have a go at that if you like (needs
> a little care to be sure we won't overflow the tmp buffer).

I added that code for a reason. But I have to be careful not to depend
on the FreeBSD specific implementation.

--
How To Keep A Healthy Level Of Insanity:

8. Don't use any punctuation marks.

Reply all
Reply to author
Forward
0 new messages