tostring vs. nan, inf

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

tostring vs. nan, inf

Alexander Gladysh
Hi, list!

As opposed to other numbers, for inf and nan tostring() returns values
that Lua can not read back:

Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
> return tostring(1/0)
inf
> return tostring(-1/0)
-inf
> return tostring(0/0)
nan
> return assert(loadstring("return inf, nan"))()
nil nil
> return assert(loadstring("return -inf"))()
[string "return -inf"]:1: attempt to perform arithmetic on global
'inf' (a nil value)
stack traceback:
        [string "return -inf"]:1: in main chunk
        (tail call): ?
        [C]: ?

This makes it harder to write serialization functions.

I do not think that it is worth the hassle of adding inf and nan
keywords to the language. (Also, one can simply define them as global
variables — which I find aesthetically unpleasant.)

But, maybe, change tostring() so it would return "1/0", "-1/0" and
"0/0" instead of inf, -inf and nan? Even the number of characters
would be the same. (Not sure though, if that would be a good thing for
the case when Lua is compiled with e.g. integer numbers.)

Any thoughts?

Alexander.

Reply | Threaded
Open this post in threaded view
|

Re: tostring vs. nan, inf

David Manura
On Tue, Apr 10, 2012 at 12:54 AM, Alexander Gladysh <[hidden email]> wrote:
>[ ...] Lua can not read back:
>> return tostring(1/0)
>inf

Unfortunately, not only can it not be read back, but what that prints
is also compiler dependent [1].

[1] http://wiki.apache.org/stdcxx/FloatingPoint

Reply | Threaded
Open this post in threaded view
|

Re: tostring vs. nan, inf

Krunal Rao

Not in LuaJIT if I remember correctly.

On Apr 10, 2012 6:19 AM, "David Manura" <[hidden email]> wrote:
On Tue, Apr 10, 2012 at 12:54 AM, Alexander Gladysh <[hidden email]> wrote:
>[ ...] Lua can not read back:
>> return tostring(1/0)
>inf

Unfortunately, not only can it not be read back, but what that prints
is also compiler dependent [1].

[1] http://wiki.apache.org/stdcxx/FloatingPoint

Reply | Threaded
Open this post in threaded view
|

Re: tostring vs. nan, inf

Luiz Henrique de Figueiredo
In reply to this post by Alexander Gladysh
> As opposed to other numbers, for inf and nan tostring() returns values
> that Lua can not read back:

In Lua 5.1 can convert "inf" and "nan" with tonumber. (But not in Lua 5.2.)

> one can simply define them as global variables

This seems to me to be a good compromise if you want to convert those
values frequently.

> But, maybe, change tostring() so it would return "1/0", "-1/0" and
> "0/0" instead of inf, -inf and nan?

You can redefine tostring to do that if you need this feature.

Reply | Threaded
Open this post in threaded view
|

Re: tostring vs. nan, inf

Alexander Gladysh
On Tue, Apr 10, 2012 at 14:58, Luiz Henrique de Figueiredo
<[hidden email]> wrote:
>> As opposed to other numbers, for inf and nan tostring() returns values
>> that Lua can not read back:
>
> In Lua 5.1 can convert "inf" and "nan" with tonumber. (But not in Lua 5.2.)
>
>> one can simply define them as global variables
>
> This seems to me to be a good compromise if you want to convert those
> values frequently.

Wouldn't work for Windows ( 1.#INF) with stock Lua.

Alexander.

Reply | Threaded
Open this post in threaded view
|

Re: tostring vs. nan, inf

martinwguy
On 10 April 2012 13:38, Alexander Gladysh <[hidden email]> wrote:
> On Tue, Apr 10, 2012 at 14:58, Luiz Henrique de Figueiredo
> <[hidden email]> wrote:
>>> one can simply define them as global variables
>>
>> This seems to me to be a good compromise if you want to convert those
>> values frequently.
>
> Wouldn't work for Windows ( 1.#INF) with stock Lua.

So your local solution seems to be to redefine tostring() to trap
these three values and print something that will regenerate them.  On
this implementation (Linux/x86) that seems to be possible with inf and
-inf but I don't see how to detect nan portably.

inf = 1/0
nan = 0/0
print( inf == inf)
true
print( nan == nan )
false

Reply | Threaded
Open this post in threaded view
|

Re: tostring vs. nan, inf

liam mail
On 10 April 2012 13:13, Martin Guy <[hidden email]> wrote:

> On 10 April 2012 13:38, Alexander Gladysh <[hidden email]> wrote:
>> On Tue, Apr 10, 2012 at 14:58, Luiz Henrique de Figueiredo
>> <[hidden email]> wrote:
>>>> one can simply define them as global variables
>>>
>>> This seems to me to be a good compromise if you want to convert those
>>> values frequently.
>>
>> Wouldn't work for Windows ( 1.#INF) with stock Lua.
>
> So your local solution seems to be to redefine tostring() to trap
> these three values and print something that will regenerate them.  On
> this implementation (Linux/x86) that seems to be possible with inf and
> -inf but I don't see how to detect nan portably.
>
> inf = 1/0
> nan = 0/0
> print( inf == inf)
> true
> print( nan == nan )
> false
>

Hehe that is how you detect nan, it is never equal to itself; also
don't forget negative infinity -1/0.0

Liam

Reply | Threaded
Open this post in threaded view
|

Re: tostring vs. nan, inf

Luiz Henrique de Figueiredo
In reply to this post by martinwguy
> but I don't see how to detect nan portably.

function isnan(x) return x~=x end
function isinf(x) return (x+1)==x end

See http://lua-users.org/lists/lua-l/2005-02/msg00758.html for alternatives
and my lmathx for a C implementation:
        http://www.tecgraf.puc-rio.br/~lhf/ftp/lua/#lmathx

Reply | Threaded
Open this post in threaded view
|

Re: tostring vs. nan, inf

Patrick Rapin
> function isnan(x) return x~=x end
> function isinf(x) return (x+1)==x end

Well, there seems to be a problem with the second one :

> return 1e16
1e+016
> return isinf(1e16)
true

Reply | Threaded
Open this post in threaded view
|

Re: tostring vs. nan, inf

Enrico Colombini
On 10/04/2012 15.39, Patrick Rapin wrote:
>> function isnan(x) return x~=x end
>> function isinf(x) return (x+1)==x end
>
> Well, there seems to be a problem with the second one :
>
>> return 1e16
> 1e+016
>> return isinf(1e16)
> true

Maybe (x*10) instead of (x+1)?

--
   Enrico

Reply | Threaded
Open this post in threaded view
|

Re: tostring vs. nan, inf

Krunal Rao
In reply to this post by Patrick Rapin

Check equality of math.abs(x) with math.huge.

On Apr 10, 2012 2:40 PM, "Patrick Rapin" <[hidden email]> wrote:
> function isnan(x) return x~=x end
> function isinf(x) return (x+1)==x end

Well, there seems to be a problem with the second one :

> return 1e16
1e+016
> return isinf(1e16)
true

Reply | Threaded
Open this post in threaded view
|

Re: tostring vs. nan, inf

Luiz Henrique de Figueiredo
In reply to this post by Patrick Rapin
> > function isnan(x) return x~=x end
> > function isinf(x) return (x+1)==x end
>
> Well, there seems to be a problem with the second one :
>
> > return 1e16
> 1e+016
> > return isinf(1e16)
> true

Sorry. This should work:

function isinf(x) return (1/x)==0 end

Reply | Threaded
Open this post in threaded view
|

Re: tostring vs. nan, inf

Patrick Rapin
To test for all 3 special numbers (Inf, -Inf and NaN) in the same
time, one could do so :

function isspecial(n)
  n = n * 0
  return n ~= n
end

Reply | Threaded
Open this post in threaded view
|

Re: tostring vs. nan, inf

martinwguy
Getting back to the original question, this seems to work on
i386/linux and avr32/embedded newlib. Can people test on other
platforms?

-- version of tostring that serialises inf, -inf and nan in a way that
-- will allow you to read them back in again.
do
  local _tostring = tostring
  function tostring(x)
    if type(x) ~= "number" then
      return _tostring(x)
    end
    -- Trap special cases inf, -inf and nan
    if x == 1/0 then return "(1/0)" end      -- inf
    if x == -1/0 then return "(-1/0)" end    -- -inf
    if x ~= x then return "(0/0)" end        -- nan
    return(_tostring(x))                     -- other
  end
end

-- Make sure everything prints the same when converted to string and back
function test()
  local s = { -1, 0, 1, 1e-16, 1e16, 1/0, -1/0, 0/0 }
  local before, after = "", ""
  -- save initial string values
  for _,v in ipairs(s) do
    before = before .. tostring(v)
  end
  -- convert there and back again
  for i,v in ipairs(s) do
    s[i] = assert(loadstring("return " .. tostring(v)))()
  end
  -- see what the result is
  for _,v in ipairs(s) do
    after = after .. tostring(v)
  end
  if before == after then
    print "PASS"
  else
    print("Before: "..before)
    print("After : "..after)
  end
end

test()

Reply | Threaded
Open this post in threaded view
|

Re: tostring vs. nan, inf

Luiz Henrique de Figueiredo
> this seems to work on i386/linux and avr32/embedded newlib.
> Can people test on other platforms?

Works fine in Mac OS X 10.6.8 in both Lua 5.1 and 5.2.

Reply | Threaded
Open this post in threaded view
|

Re: tostring vs. nan, inf

Jose Torre-Bueno
In reply to this post by Luiz Henrique de Figueiredo
But I notice nan cannot be assigned to a variable, the variable is set to nil.

> c = nan
> =isnan(c)
false
> =c
nil

but a variable with nan as its value can set another variable to nan:

> a = 0/0
> = isnan(a)
true
> c = a
> = c
nan

further two variables set to nan are not equal to each other:
> a = 0/0
> b = 0/0
> = a==b
false

But nan is equal to itself:
> = nan == nan
true
> = nan
nil
>



this says to me that nan is not a pseudo constant in the same way nil is.  I assume there is something subtle going on here.  Perhaps somebody can explain why this is so.


On Apr 10, 2012, at 5:38 AM, Luiz Henrique de Figueiredo wrote:

>> but I don't see how to detect nan portably.
>
> function isnan(x) return x~=x end
> function isinf(x) return (x+1)==x end
>
> See http://lua-users.org/lists/lua-l/2005-02/msg00758.html for alternatives
> and my lmathx for a C implementation:
> http://www.tecgraf.puc-rio.br/~lhf/ftp/lua/#lmathx
>


Reply | Threaded
Open this post in threaded view
|

Re: tostring vs. nan, inf

Peter Cawley
On Thu, Apr 12, 2012 at 4:26 PM, Jose Torre-Bueno <[hidden email]> wrote:
> this says to me that nan is not a pseudo constant in the same way nil is.  I assume there is something subtle going on here.  Perhaps somebody can explain why this is so.

Correct, nan is not a pseudo constant. Infact, unless you make it
otherwise, nan isn't anything at all. It is a named global variable
like any other, and the default value for global variables is nil.

> =foo
nil
> =bar
nil
> =baz
nil
> =nan
nil

Reply | Threaded
Open this post in threaded view
|

Re: tostring vs. nan, inf

Coda Highland
In reply to this post by Jose Torre-Bueno
On Thu, Apr 12, 2012 at 10:26 AM, Jose Torre-Bueno <[hidden email]> wrote:
> But I notice nan cannot be assigned to a variable, the variable is set to nil.

That's because nan isn't a constant. It's just a variable that happens
to be undefined. If you say "nan = 0/0" then it'll behave as you'd
expect.

/s/ Adam

Reply | Threaded
Open this post in threaded view
|

Re: tostring vs. nan, inf

Elias Barrionovo
On Thu, Apr 12, 2012 at 12:31 PM, Coda Highland <[hidden email]> wrote:
> On Thu, Apr 12, 2012 at 10:26 AM, Jose Torre-Bueno <[hidden email]> wrote:
>> But I notice nan cannot be assigned to a variable, the variable is set to nil.
>
> That's because nan isn't a constant. It's just a variable that happens
> to be undefined. If you say "nan = 0/0" then it'll behave as you'd
> expect.

Indeed. A cool trolling exercise is to do
  nan = 1/0
  inf   = 0/0
  print(nan, inf) -- "inf, -nan" (for some reason, in my computer 0/0
is always -nan)

Reminds me of Python where, since all values are passed as reference, on can do
  True, False = False, True
on the middle of a huge source and laugh while every developer
desperately tries to track the bug.



--
NI!