Not a number is a number, problem

Anything beyond the basics in using the LiveCode language. Share your handlers, functions and magic here.

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

bogs
Posts: 5435
Joined: Sat Feb 25, 2017 10:45 pm

Re: Not a number is a number, problem

Post by bogs » Wed Mar 17, 2021 6:42 pm

This question is just my curiosity, I didn't actually take the time to go back through all 3 pages of this thread to find out for myself :P

NAN as I understand it stands for "Not A Number", and (apparently) is an undocumented feature (i.e. no dictionary entry), however, doesn't the entry for comparing numbers already exist, and is well documented? For example, 2 lines that compare whether something is a number from the dictionary -
x is a number
y is strictly a number

Aside from the above two examples, there is also this function to determine a number -

Use the isNumber function to determine whether a value is a number. For example, attempting to do an arithmetic operation on a value that's not a number causes an error. You can check the value beforehand to prevent this.

The question becomes, what is, from my point of view as a 3rd rate heathen hack, the dubious value of trying to use something not well defined as even being part of the language?
Image

Davidv
Posts: 77
Joined: Sun Apr 09, 2006 1:51 am
Location: Australia

Re: Not a number is a number, problem

Post by Davidv » Wed Mar 17, 2021 11:03 pm

Hello John, thank you for your comments on this.

To make sure I understand, it seems to me you are saying a couple of things. First, that the sort order between the two lists may be inconsistent. Second, that my code would fail in any case on an 888 example.

The sort order of the source data is as presented in a CSV report from a provider. After much is stripped, here is a relevant fragment (with some elision of the unnecessary):
MQG,149.600
NAN,5.960
NCM,24.020
The data order with which it is compared is determined by a simple sort in LC. Manual comparison shows that these are in the same order, so NAN is being compared with NAN at the right point in each list. If I use value() as later suggested, then it works for NAN as well.

Regarding numeric, I created a fake record of a company with ticker 888, and another with 14D which is on the ASX. These sort correctly in my data and 14D is reported in the same place in a provider report. There is no problem handling numbers in these situations, so it does not appear to me that failure is inevitable in the code. Well, it does not fail anywhere but for a raw NAN, and I have been using it since an early form in HyperCard (I am currently bringing the code into the 21st C in a significant redesign).

cheers
David

Davidv
Posts: 77
Joined: Sun Apr 09, 2006 1:51 am
Location: Australia

Re: Not a number is a number, problem

Post by Davidv » Wed Mar 17, 2021 11:13 pm

Hi bogs,

Sadly, I have no option* on whether NAN is in the list, which I think was the point you were reaching. Value() is the function now solving the problem but I will not routinely be writing that into other code without a real possibility a NAN comparison will be needed.

* Not really true. Divestment is an option :)

cheers
David

johnf923
Posts: 18
Joined: Tue Feb 23, 2021 8:20 pm

Re: Not a number is a number, problem

Post by johnf923 » Thu Mar 18, 2021 12:27 am

Hi David

I didn't mean to suggest that the order was inconsistent between the two lists: in fact I was assuming it was the same. My problem is with the use of the > and < operators in your pseudo-code, which seems to rely on the assumption that if a list contains codes A, B and C then the expressions A<B and B<C will both be true - and that isn't necessarily the case.

I've just created a test stack with a button and a card field called "log", and put this code into the button:

Code: Select all

on mouseUp
   put empty into cd fld "log"
   put "888",  "INF",  "NAN", "PPP" into codes
   repeat with i=1 to (the number of items in codes) - 1
      put item i of codes into bar
      put item i+1 of codes into foo
      -- report result of comparison between adjacent items
      put return & bar && "<" && foo && "is" && (bar < foo) after cd fld "log"
   end repeat
end mouseUp
The output was

Code: Select all

888 < INF is true
INF < NAN is false
NAN < PPP is true
I think the second line is the smoking gun: the "<" operator is coercing INF and NAN to their floating point equivalents and delivering a result that isn't what might be expected. A good example (IMHO) of the perils of weakly typed languages.

I'm glad to see that you're now happy that your code is working, so perhaps we should leave it there.

And @bogs:
I like your point that NAN is not in the dictionary. Since there is an entry for infinity, I would think that NAN should get an entry too on the grounds that they're both LiveCode constructs for accessing the underlying floating point mechanism.

John

Davidv
Posts: 77
Joined: Sun Apr 09, 2006 1:51 am
Location: Australia

Re: Not a number is a number, problem

Post by Davidv » Thu Mar 18, 2021 1:19 am

John, it's a smoking gun for what? Only that NAN is neither documented (as noted pages ago) nor consistent in its interpretation within a context that itself is consistent. An assumption of string comparisons should be tolerable given NAN is undocumented. No, I am not happy with the workaround which is why I have the problem registered in a bug report.

By the way, there is an ASX company with code INF but all string comparisons of INF are correct (equal, neither greater nor less) whereas NAN is not less than itself, is equal to itself (so far so good) but is also greater than itself. That is the problem.

David

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9655
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: Not a number is a number, problem

Post by dunbarx » Thu Mar 18, 2021 2:41 am

Hmmm.

I didn't know this wold compile:

Code: Select all

on mouseUp
   put "888",  "INF",  "NAN", "PPP" into codes
end mouseUp
So many new-fangled ways of doing things.

Craig

Davidv
Posts: 77
Joined: Sun Apr 09, 2006 1:51 am
Location: Australia

Re: Not a number is a number, problem

Post by Davidv » Thu Mar 18, 2021 8:06 am

I can simplify these many pages for future readers by summarising thus:

In the message box, or a script as you please, test the following or any other pair of "identical" literals:

put "NAN" < "NAN"
put "NAN" = "NAN"
put "NAN" > "NAN"

If you do not get false, true, false, respectively then it is a bug. For the purposes of these comparisons I frankly do not care whether the engine thinks NAN is a number or a string or a turtle snorting an infinite line of coke, so long as there are two of the same.

Documentation of NAN may even assist in LC's analysis of the bug.

:)

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9655
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: Not a number is a number, problem

Post by dunbarx » Thu Mar 18, 2021 2:06 pm

David.

Nope. I get:

Code: Select all

"NAN" < "NAN"  ("false")
"NAN" = "NAN"    ("true")
"NAN" > "NAN"    ("true")
Do not think for a moment this makes me feel any better.

And what makes me feel even worse:

Code: Select all

"infinity" > "nan"    ("true")
And I thought I knew my "ABC's"

To boil just part of this discussion down, and as you well know, how do certain strings escape from their quotation marks? Obviously the engine is being fooled somewhere in its resolving process.

Craig

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9655
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: Not a number is a number, problem

Post by dunbarx » Thu Mar 18, 2021 2:08 pm

David.

I almost forgot. How do you and I get different results for:

Code: Select all

"NAN" > "NAN"    ("true")
???

Craig

johnf923
Posts: 18
Joined: Tue Feb 23, 2021 8:20 pm

Re: Not a number is a number, problem

Post by johnf923 » Thu Mar 18, 2021 3:20 pm

Indeed: I get false, false, true (LC 9 6 2 rc3).

Where we differ is in whether it's a bug, although I certainly agree it's inconsistent. The Wikipedia summary of the IEEE 754 standard says of NaN (the number):
Any comparison with NaN is treated as unordered.
which as I read it says that if you try to compare NaN the number with anything, all bets are off. I don't believe this is a LC issue - for instance in Tcl this happens

Code: Select all

$ tclsh
% expr NaN < NaN
0
% expr NaN == NaN
0
% expr NaN > NaN
0
% 
and in C (note: I had to substitute "/" for "." in all code that follows because the forum software seems not to like dots that are embedded between other characters):

Code: Select all

#include <math/h>
#include <stdio/h>

int main() {
  float mynan = nanf("abc");
  printf("NaN < NaN: %d\n", (mynan < mynan));
  printf("NaN == NaN: %d\n", (mynan == mynan));
  printf("NaN > NaN: %d\n", (mynan > mynan));
}
compiled with

Code: Select all

gcc -o nantest nantest/c -lm
prints

Code: Select all

$ ./nantest 
NaN < NaN: 0
NaN == NaN: 0
NaN > NaN: 0
$
Ok, how about Python?

Code: Select all

$ python3
Python 3/8/5 (default, Jan 27 2021, 15:41:15) 
[GCC 9/3/0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import math
>>> x = math/nan
>>> x < x
False
>>> x == x
False
>>> x < x
False
>>> 
So I still think that the real issue is unwanted coercions when you're really after string comparisons. I'm only just learning LiveCode (though I was a user of HyperCard from when it first came out) and as far as I can see LC doesn't have a string comparison function like C's strcmp. That being so, to force string comparison when things can seem to be numbers you have to use this idiom (borrowed from shell programming) or something equivalent:

Code: Select all

put "INF" into bar
put "NAN" into foo
-- the wrong way...
put bar < foo
-- gives false because it's treating INF and NAN as numbers, which they are
-- but
put ("x" & bar) < ("x" & foo)
-- gives true because it forces string comparison

bogs
Posts: 5435
Joined: Sat Feb 25, 2017 10:45 pm

Re: Not a number is a number, problem

Post by bogs » Thu Mar 18, 2021 3:37 pm

johnf923 wrote:
Thu Mar 18, 2021 3:20 pm
and in C (note: I had to substitute "/" for "." in all code that follows because the forum software seems not to like dots that are embedded between other characters):
In about 5 more posts, that will no longer be a problem for you ;)
Image

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9655
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: Not a number is a number, problem

Post by dunbarx » Thu Mar 18, 2021 4:56 pm

Hmmm.

So "NAN" is so odd, that different machines can get different values.

I think this extends, really extends, the notion of a "floating" point number. I would say it is a drifting point number.
can see LC doesn't have a string comparison
Not sure what the C equivalent is, but LC does indeed have comprehensive string tools. Have you run across a case where you found LC coming up short?

Craig

johnf923
Posts: 18
Joined: Tue Feb 23, 2021 8:20 pm

Re: Not a number is a number, problem

Post by johnf923 » Thu Mar 18, 2021 5:15 pm

dunbarx wrote:
Thu Mar 18, 2021 4:56 pm
Hmmm.
can see LC doesn't have a string comparison
Not sure what the C equivalent is, but LC does indeed have comprehensive string tools. Have you run across a case where you found LC coming up short?

Craig
Not really, although in fairness I haven't got very far into the language yet. I confess to a personal preference for strongly typed languages but I accept weak typing as a LC design choice - and because of the HyperCard inheritance, it has to be that way. For me, it's LC's portability and media processing that have me hooked.

John

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9655
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: Not a number is a number, problem

Post by dunbarx » Thu Mar 18, 2021 6:40 pm

John. I go back to 1987 with HC. You already have a terrific head start in LC if you used HC to any reasonable extent.

Typeless, er, typing is fundamental to xTalks, and I believe the advantages outweigh the disadvantages. I suppose it is easier to misapply ones code in a typeless language (add 3 to x, where x is not a number). I am not sure if there is an execution speed hit, since I do not know how strongly the compiler types variables based on context as opposed to explicitly by the programmer.

LC builder requires both declaring and typing.

Craig

johnf923
Posts: 18
Joined: Tue Feb 23, 2021 8:20 pm

Re: Not a number is a number, problem

Post by johnf923 » Thu Mar 18, 2021 11:39 pm

I think the question of strong vs weak typing is a matter of context: different languages work best for different tasks. In other words, I'm happy to express my opinion but not to quarrel with anyone else's.

Except that I can't resist mentioning that the LiveCode engine is itself written in (strongly-typed) C++ :wink:

Now, I found that out because I just downloaded the source code in an effort to see why the

Code: Select all

NAN < NAN
NAN = NAN
NAN > NAN
comparisons were yielding results that seemed to be inconsistent, and that were inconsistent with the results returned by all the other languages I tried.

And after a bit of searching I found in the file exec-logic/cpp (in which I have had to substitute "/" instead of "." before the forum software would let me post) the function definition for

Code: Select all

static bool MCLogicCompareTo(...)
and in that function I believe I can see some logic that will in some cases use the value of an uninitialized variable. If I'm right, that has to be bad news.

When the forum software lets me escape from what I believe to be "Newbie quarantine" I'll look into reporting that as a bug.

John

Post Reply

Return to “Talking LiveCode”