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.




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

Raspunde prin e-mail lui