Not a number is a number, problem
Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller
Re: Not a number is a number, problem
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
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?
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?
Re: Not a number is a number, problem
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):
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
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):
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.MQG,149.600
NAN,5.960
NCM,24.020
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
Re: Not a number is a number, problem
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
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
Re: Not a number is a number, problem
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:
The output was
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
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
Code: Select all
888 < INF is true
INF < NAN is false
NAN < PPP is true
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
Re: Not a number is a number, problem
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
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
-
- VIP Livecode Opensource Backer
- Posts: 9669
- Joined: Wed May 06, 2009 2:28 pm
- Location: New York, NY
Re: Not a number is a number, problem
Hmmm.
I didn't know this wold compile:
So many new-fangled ways of doing things.
Craig
I didn't know this wold compile:
Code: Select all
on mouseUp
put "888", "INF", "NAN", "PPP" into codes
end mouseUp
Craig
Re: Not a number is a number, problem
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.
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.
-
- VIP Livecode Opensource Backer
- Posts: 9669
- Joined: Wed May 06, 2009 2:28 pm
- Location: New York, NY
Re: Not a number is a number, problem
David.
Nope. I get:
Do not think for a moment this makes me feel any better.
And what makes me feel even worse:
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
Nope. I get:
Code: Select all
"NAN" < "NAN" ("false")
"NAN" = "NAN" ("true")
"NAN" > "NAN" ("true")
And what makes me feel even worse:
Code: Select all
"infinity" > "nan" ("true")
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
-
- VIP Livecode Opensource Backer
- Posts: 9669
- Joined: Wed May 06, 2009 2:28 pm
- Location: New York, NY
Re: Not a number is a number, problem
David.
I almost forgot. How do you and I get different results for:
???
Craig
I almost forgot. How do you and I get different results for:
Code: Select all
"NAN" > "NAN" ("true")
Craig
Re: Not a number is a number, problem
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):
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):
compiled with
prints
Ok, how about Python?
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:
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):
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 happensAny comparison with NaN is treated as unordered.
Code: Select all
$ tclsh
% expr NaN < NaN
0
% expr NaN == NaN
0
% expr NaN > NaN
0
%
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));
}
Code: Select all
gcc -o nantest nantest/c -lm
Code: Select all
$ ./nantest
NaN < NaN: 0
NaN == NaN: 0
NaN > NaN: 0
$
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
>>>
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
-
- VIP Livecode Opensource Backer
- Posts: 9669
- Joined: Wed May 06, 2009 2:28 pm
- Location: New York, NY
Re: Not a number is a number, problem
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.
Craig
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.
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?can see LC doesn't have a string comparison
Craig
Re: Not a number is a number, problem
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
-
- VIP Livecode Opensource Backer
- Posts: 9669
- Joined: Wed May 06, 2009 2:28 pm
- Location: New York, NY
Re: Not a number is a number, problem
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
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
Re: Not a number is a number, problem
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++
Now, I found that out because I just downloaded the source code in an effort to see why the
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
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
Except that I can't resist mentioning that the LiveCode engine is itself written in (strongly-typed) C++
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
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(...)
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