Using numbers as float

classic Classic list List threaded Threaded
16 messages Options
Reply | Threaded
Open this post in threaded view
|

Using numbers as float

jose marin2
Hi.

I'm compiling Lua to use floats, altering the file
luser_number.h .

The macro lua_str2number uses strtod (returns a
double).

I could cast to (float)strtod, but I'm worried abou
performance.

Is there some fast way of convert a string to a float?

Thanks!




		
_______________________________________________________ 
Abra sua conta no Yahoo! Mail: 1GB de espaço, alertas de e-mail no celular e anti-spam realmente eficaz. 
http://mail.yahoo.com.br/

Reply | Threaded
Open this post in threaded view
|

Re: Using numbers as float

Asko Kauppi

I've used the attached file (hope it gets through?).


Attachment: flt2str.c
Description: Binary data



Jose Marin kirjoitti 29.6.2006 kello 22.01:

Hi.

I'm compiling Lua to use floats, altering the file
luser_number.h .

The macro lua_str2number uses strtod (returns a
double).

I could cast to (float)strtod, but I'm worried abou
performance.

Is there some fast way of convert a string to a float?

Thanks!




		
_______________________________________________________
Abra sua conta no Yahoo! Mail: 1GB de espaço, alertas de e-mail no celular e anti-spam realmente eficaz.
http://mail.yahoo.com.br/

Reply | Threaded
Open this post in threaded view
|

Re: Using numbers as float

jose marin2
Thanks, Asko, I will see the file you sent, but there
is a "standard" way of convert a string to a float?

Is everybody using Lua numbers as double?

If you are using float, how did you do the convertion
from string to float?




		
_______________________________________________________ 
Novidade no Yahoo! Mail: receba alertas de novas mensagens no seu celular. Registre seu aparelho agora! 
http://br.mobile.yahoo.com/mailalertas/ 
 


Reply | Threaded
Open this post in threaded view
|

Re: Using numbers as float

Sam Roberts-2
In reply to this post by jose marin2
On Thu, Jun 29, 2006 at 07:01:58PM +0000, Jose Marin wrote:
> I'm compiling Lua to use floats, altering the file
> luser_number.h .
> 
> The macro lua_str2number uses strtod (returns a
> double).
> 
> I could cast to (float)strtod, but I'm worried abou
> performance.

I very much doubt performance would be a problem,

> Is there some fast way of convert a string to a float?

but you could use strtof() instead of strtod().

Sam


Reply | Threaded
Open this post in threaded view
|

Re: Using numbers as float

Mark Edgar
In reply to this post by jose marin2
Jose Marin wrote:
Hi.

I'm compiling Lua to use floats, altering the file
luser_number.h .

The macro lua_str2number uses strtod (returns a
double).

I could cast to (float)strtod, but I'm worried abou
performance.

Is there some fast way of convert a string to a float?

Thanks!

strtod() works just fine; no cast is required:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
  float x = strtod("3.2", NULL);
  printf("%f\n", x);
  return 0;
}

You probably won't find anything faster, as your implementation's strtod() is probably written in nice fast assembly.

If you have a C99 conforming system, you can use strtof() instead. I don't know that you'll notice a performance difference between strtod() and strtof().

					-Mark

Reply | Threaded
Open this post in threaded view
|

Re: Using numbers as float

jose marin2
In reply to this post by Sam Roberts-2
Hi, Sam.

I couldn't find the strtof function!
strtod it's on stdlib.h, but I haven't found strtof
anywhere!



__________________________________________________
Fale com seus amigos  de graça com o novo Yahoo! Messenger 
http://br.messenger.yahoo.com/ 

Reply | Threaded
Open this post in threaded view
|

Re: Using numbers as float

jose marin2
In reply to this post by Mark Edgar
I think your right, Mark.

I'll use strtod.
Sometimes, I think I worry too much with perfomance!



__________________________________________________
Fale com seus amigos  de graça com o novo Yahoo! Messenger 
http://br.messenger.yahoo.com/ 

Reply | Threaded
Open this post in threaded view
|

Re: Using numbers as float

Glenn Maynard
In reply to this post by Mark Edgar
On Thu, Jun 29, 2006 at 12:41:14PM -0700, Mark Edgar wrote:
> strtod() works just fine; no cast is required:
> 
> #include <stdio.h>
> #include <stdlib.h>
> 
> int main(void)
> {
>   float x = strtod("3.2", NULL);

I think VC will say "warning: implicit conversion loses data" or
something to that effect.  Which I do find to be a useful warning;
I prefer to get float vs. double correct, and do like to be told
if I'm being inconsistent.  (It isn't smart enough to not warn
about "uint8_t = i & 0xFF", though, and it's mildly annoying to
have to cast that to shut it up.  Net win, though, in my opinion.)

> You probably won't find anything faster, as your implementation's 
> strtod() is probably written in nice fast assembly.

The strtod() implementations I've seen havn't been assembly; it's
a complicated conversion to do right.  (Maybe some inner loops could
benefit, but better compilers have increased the threshold of it being
worth doing so ...)

> If you have a C99 conforming system, you can use strtof() instead.  I 
> don't know that you'll notice a performance difference between strtod() 
> and strtof().

You'll see a serious performance difference on systems without hardware
doubles.  You'd probably know if you were on one of those, though, and
be compiling Lua yourself to be sure it's using floats.

Note that I've seen strtof() implementations that are simply casted
wrappers around strtod(), where I had to change it by hand.

-- 
Glenn Maynard

Reply | Threaded
Open this post in threaded view
|

Re: Using numbers as float

Andreas Krinke
In reply to this post by jose marin2
Jose Marin wrote:
Hi, Sam.

I couldn't find the strtof function!
strtod it's on stdlib.h, but I haven't found strtof
anywhere!

strtod is defined by ANSI C, strtof at first by the C99 standard. So maybe your stdlib.h is not C99 compatible?

-- Andi

Reply | Threaded
Open this post in threaded view
|

Re[2]: Using numbers as float

Dmitriy Iassenev
hello,

we use floats in Lua, but there is a problem, which, probably, is
because of this change (we still use Lua 5.02). When iterating via a
table, which indices are numbers, runtime error occured:

"invalid key for 'next'"

Therefore we iterate via Lua tables in the following way (we presume
that table to iterate is on the top of the stack):

// standard cycle
        lua_pushnil     (state);
        for ( ; lua_next(state,-2); )
            lua_pop     (state,1);
            
// modified cycle
        lua_pushnil     (state);
        for ( ; lua_next(state,-2); ) {
            // start of the magic change
            if (lua_isnumber(state,-2)) {
                lua_Number      next = lua_tonumber(state,-2);
                lua_pop         (state,2);
                lua_pushnumber  (state,next);
                continue;
            }
            // end of the magic change
            lua_pop      (state,1);
        }

-- 
Best regards,
 Dmitriy                            [hidden email]


Reply | Threaded
Open this post in threaded view
|

Re: Using numbers as float

Mike Pall-62
Hi,

Dmitriy Iassenev wrote:
> we use floats in Lua, but there is a problem, which, probably, is
> because of this change (we still use Lua 5.02). When iterating via a
> table, which indices are numbers, runtime error occured:
> 
> "invalid key for 'next'"

There are issues with floats, but table iteration should not be
one of them (unless your arrays have more than 2^24 elements).

The most common cause for this message is using lua_tostring() or
lua_tonumber() on the key inside the iteration loop. This call
may convert the key to the other type which in turn breaks the
iteration. One needs to copy the key with lua_pushvalue() before
using either call (it doesn't matter for the value).

The other common cause is modifying the table during traversal.
Only replacing existing keys with new values (including nil) is
allowed.

>             if (lua_isnumber(state,-2)) {
>                 lua_Number      next = lua_tonumber(state,-2);

Ouch! lua_isnumber() returns true for numbers _and_ strings which
can be converted to numbers. In fact it does a temporary
conversion, but doesn't store the resulting number. And then
lua_tonumber() has to repeat the (expensive) conversion. I'm
pretty sure you don't want to do this during a table traversal.
It may break the traversal, too (see above).

Avoid lua_isnumber() wherever possible, unless you really want
the auto-coercion. And even then you may want to use
lua_tonumber() directly and only add a lua_isnumber() check if
zero is returned. This is e.g. what luaL_checknumber() does.

You usually want to use this:
  if (lua_type(L, -2) == LUA_TNUMBER) ...
Or this:
  switch (lua_type(L, -2)) { case LUA_TNUMBER: ... case LUA_Txx: ... }


[BTW: Whatever Lua 5.2 or 6.0 may look like, but may I suggest
redesigning or at least renaming the auto-coercive API calls?]

Bye,
     Mike

Reply | Threaded
Open this post in threaded view
|

Re: Using numbers as float

Roberto Ierusalimschy
> [BTW: Whatever Lua 5.2 or 6.0 may look like, but may I suggest
> redesigning or at least renaming the auto-coercive API calls?]

Only lua_tostring does auto-coercion. lua_tonumber (and lua_isnumber)
does not modify the original object (at the cost of performing the
conversion at every new call).

-- Roberto

Reply | Threaded
Open this post in threaded view
|

Re: Using numbers as float

Sam Roberts-2
On Fri, Jun 30, 2006 at 10:54:01AM -0300, Roberto Ierusalimschy wrote:
> > [BTW: Whatever Lua 5.2 or 6.0 may look like, but may I suggest
> > redesigning or at least renaming the auto-coercive API calls?]
> 
> Only lua_tostring does auto-coercion. lua_tonumber (and lua_isnumber)
> does not modify the original object (at the cost of performing the
> conversion at every new call).

I lost a number of hours trying to get a table coercion working, I had
code like:

  if(lua_isstring())
	  lua_tostring()
  else if(lua_isnumber())
	  lua_tonumber()

I knew lua_tostring() would coerce the type of the value on the stack,
but it never occurred to me that lua_isstring() would return true if
it is NOT a string.

I guess this is just a gotcha for new lua users, and now that I know I
don't mind so much, but it sure surprised me.

Sam


Reply | Threaded
Open this post in threaded view
|

Re: Using numbers as float

Asko Kauppi
In reply to this post by jose marin2

Experience shows that performance can only be measured, not "intuitively" hypothised. On some platforms (say, ARM without FPU), doubles really are a brake; on others they're as fast (or faster) as float. I played with this earlier, and making Lua truly double-free demands more than "meets the eye" at first. :)

-asko


Jose Marin kirjoitti 29.6.2006 kello 22.58:


I think your right, Mark.

I'll use strtod.
Sometimes, I think I worry too much with perfomance!



__________________________________________________
Fale com seus amigos  de graça com o novo Yahoo! Messenger
http://br.messenger.yahoo.com/



Reply | Threaded
Open this post in threaded view
|

Re: Using numbers as float (..and full int32 range)

Asko Kauppi
In reply to this post by Mike Pall-62

It is possible to patch Lua so, that one can use floats and full int32 range, together. That is, to have iteration etc. not limited by 2^24, and not take the baggage of doubles with you.

A tested patch on this has been sent to the authors; it is in their hands for now..

The main reason they wouldn't be taking it in, is added complexity, and (*Ban me*) use of preprocessor #ifdef's.

-asko


Mike Pall kirjoitti 30.6.2006 kello 15.03:

Hi,

Dmitriy Iassenev wrote:
we use floats in Lua, but there is a problem, which, probably, is
because of this change (we still use Lua 5.02). When iterating via a
table, which indices are numbers, runtime error occured:

"invalid key for 'next'"

There are issues with floats, but table iteration should not be
one of them (unless your arrays have more than 2^24 elements).

The most common cause for this message is using lua_tostring() or
lua_tonumber() on the key inside the iteration loop. This call
may convert the key to the other type which in turn breaks the
iteration. One needs to copy the key with lua_pushvalue() before
using either call (it doesn't matter for the value).

The other common cause is modifying the table during traversal.
Only replacing existing keys with new values (including nil) is
allowed.

            if (lua_isnumber(state,-2)) {
                lua_Number      next = lua_tonumber(state,-2);

Ouch! lua_isnumber() returns true for numbers _and_ strings which
can be converted to numbers. In fact it does a temporary
conversion, but doesn't store the resulting number. And then
lua_tonumber() has to repeat the (expensive) conversion. I'm
pretty sure you don't want to do this during a table traversal.
It may break the traversal, too (see above).

Avoid lua_isnumber() wherever possible, unless you really want
the auto-coercion. And even then you may want to use
lua_tonumber() directly and only add a lua_isnumber() check if
zero is returned. This is e.g. what luaL_checknumber() does.

You usually want to use this:
  if (lua_type(L, -2) == LUA_TNUMBER) ...
Or this:
  switch (lua_type(L, -2)) { case LUA_TNUMBER: ... case LUA_Txx: ... }


[BTW: Whatever Lua 5.2 or 6.0 may look like, but may I suggest
redesigning or at least renaming the auto-coercive API calls?]

Bye,
     Mike


Reply | Threaded
Open this post in threaded view
|

Re: Using numbers as float (..and full int32 range)

D Burgess-4
Well, I would argue that this is a fairly common requirement.
If the authors dont want this in mainstream Lua, maybe adding the
patch to the /etc directory is a way out. I presume this would
add a neglible amount of size to the distro.

I would vote for this patch, the int32 patch, coco and LHFs lposix
being added to the /etc or /patches directory of the Lua distro. If
nothing else it would reduce the number of questions on the list
and increase the chances of Lua being adopted for various projjects.


David B


Asko Kauppi wrote:

It is possible to patch Lua so, that one can use floats and full
int32 range, together. That is, to have iteration etc. not limited by
2^24, and not take the baggage of doubles with you.

A tested patch on this has been sent to the authors;  [...]