Whole numbers

Got a LiveCode personal license? Are you a beginner, hobbyist or educator that's new to LiveCode? This forum is the place to go for help getting started. Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller

stam
Posts: 3072
Joined: Sun Jun 04, 2006 9:39 pm

Re: Whole numbers

Post by stam » Sun Sep 06, 2020 2:40 pm

While not that immediately important, i do feel the integer keyword should distinguish 1.0 from 1

Admittedly the value of this is limited but it is a potential source of error, so while low priority i consider this a bug and have filed a bug report.
If you agree, please see the bug report here: https://quality.livecode.com/show_bug.cgi?id=22892

Feel free to add a 'me too' reply -- i presume this increases visibility (just guessing...)

stam
Posts: 3072
Joined: Sun Jun 04, 2006 9:39 pm

Re: Whole numbers

Post by stam » Sun Sep 06, 2020 2:53 pm

dunbarx wrote:
Sun Sep 06, 2020 2:00 pm
But then 003 would pass as an integer. By using "trunc", that oddity is removed, as well as ".".
In my mind 003 is both an integer and a 'whole number'. The '00' is the formatting of the number, not the type and it should just be a matter of formatting the number correctly. But it is an integer ;)

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10317
Joined: Wed May 06, 2009 2:28 pm

Re: Whole numbers

Post by dunbarx » Sun Sep 06, 2020 4:31 pm

Stam.

I disagree on this small point of a admittedly relatively unimportant issue. "003" is programmatically no different than "3.0". They are both formatted forms of what we think of as the concept of integers. It is not the decimal point, as opposed to leading zeros, that matter, it is our idea of what an integer is. It is all computer-think.

I am still waiting for anyone to find a scenario where it actually makes a difference, beyond the idea of formatting, either in data entry or in what is considered the "correct" form. Something like "3 + 4 <> 3.0 + 04"

Craig

SparkOut
Posts: 2946
Joined: Sun Sep 23, 2007 4:58 pm

Re: Whole numbers

Post by SparkOut » Sun Sep 06, 2020 6:33 pm

I am very weak on formal mathematics. I don't know. Some of it I don't even understand, but in my simplistic view,
00000000001.0000000000000000000000000 is an integer.
00000000001.0000000000000000000000001 is very close, but not. The former is just a string representing a formatted version of 1 and the latter is a decimal representation of a non integer, also formatted as a string with leading zeroes.

In reply to you Craig, "3 + 4 = 3.0 + 04" (I believe that this is coincidentally how the LiveCode engine sees it).

I don't know what Hermann would think, he's probably within his rights to shoot me.

stam
Posts: 3072
Joined: Sun Jun 04, 2006 9:39 pm

Re: Whole numbers

Post by stam » Sun Sep 06, 2020 6:52 pm

Hi Craig,
Fun philosophical discussion :)

For what it's worth i would argue that arithmetically 003 and 3.0 are the same, but programmatically these are not - not because there is a difference in mathematical value, but because of a difference in type of variable.

Imagine this scenario: You may receive data of unknown type from some process and stick it in a variable.
If the type of data is an integer (eg. 003, 052 or 111) then it signifies an error code.
If the type of data is a float (decimal, eg 0.001, 1.5, 3.8, or yes, 1.0 ) then it's the result of a computation.

Your introspection includes the code:

Code: Select all

If tVar is an integer then...
If it's an integer - no problem, in this fictitious example you would act on the error code received.
But if this the value of a result, that say in this case could have been 1.1, 1.2, 1.5 but in this case returns 1.0, then that's a problem as integer returns true. Which means in this particular example your code would assess this as an error code, not a result value.

Arithmetically in LiveCode these are these are of course the same and it matters not when you perform arithmetic with these numbers. But if you have decisions based on type of data, this will lead to issues.

My issue is that the integer keyword fails to recognise this, which would be important in the above example (where you need to know the type of variable you're dealing with).
Many typed languages are clever and can infer the data type. In Swift, you can type

Code: Select all

var tDouble = 2.0  //infers the data type is double (ie decimal)
var tInteger = 2   //infers the data type is integer
As LiveCode is typeless language it of course doesn't make any difference when performing arithmetic (whereas in typed languages this would cause crashes), but if your decision making is based on data type, then the integer keyword failing this way is a problem...

LiveCode does an excellent job at shielding devs from many of the issues with data types, but there are tradeoffs, like in the example above.
There's a very nerdy write up on data types in programming languages on Wikipedia but i'm sure there are simpler resources online -- they would all say the same as above. But thankfully this doesn't really affect LiveCode coding in most circumstances.

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4172
Joined: Sun Jan 07, 2007 9:12 pm

Re: Whole numbers

Post by bn » Sun Sep 06, 2020 7:42 pm

As of LC 8.0 there is an "is strictly" operator.
value is strictly { nothing | a boolean | an integer | a real | a string | a binary string | an array }
Unfortunately I can not get it to work with integers. It probably reflects the internal state of LC or how it currently views value.
Maybe someone has more luck than I do.

Kind regards

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10317
Joined: Wed May 06, 2009 2:28 pm

Re: Whole numbers

Post by dunbarx » Sun Sep 06, 2020 9:13 pm

@ Bernd.

Yes, "is strictly" fails with:

Code: Select all

on  mouseUp
   if "3" is an integer then beep 2
end mouseUp
No beeps.

@Stam
I agree.

Early on, I had mentioned that there might be cases where the formatting of either data input or output might matter., and therefore LC is far too loose about what an integer is. It is this sort of scenario, not when simply doing arithmetic, that may become an issue. In LC in particular, I think this sort of "app" might come up now and then.

LC needs a label warning of lark's vomit.

Glad you notified the team.

Craig

EDIT. When I wrote the code snippet I meant to imply that if the "strictly" was inserted, there were still no beeps. This led Klaus astray>
Last edited by dunbarx on Mon Sep 07, 2020 3:06 pm, edited 1 time in total.

Klaus
Posts: 14194
Joined: Sat Apr 08, 2006 8:41 am
Contact:

Re: Whole numbers

Post by Klaus » Sun Sep 06, 2020 9:31 pm

Code: Select all

on  mouseUp
   if "3" is an integer then beep 2
end mouseUp
Hm, works here, macOS 10.14.6 and LC 9.6.1, as advertized!
Means it beeps twice after my click.

Or am I missing something obvious/the point?
Maybe your are talking about LCB?

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4172
Joined: Sun Jan 07, 2007 9:12 pm

Re: Whole numbers

Post by bn » Sun Sep 06, 2020 9:39 pm

Klaus wrote:
Sun Sep 06, 2020 9:31 pm

Code: Select all

on  mouseUp
   if "3" is an integer then beep 2
end mouseUp
Hm, works here, macOS 10.14.6 and LC 9.6.1, as advertized!
Means it beeps twice after my click.
Regarding "is strictly" you would test for

Code: Select all

if 3 is strictly an integer then beep 2
If you put 3 in quotes it is a string
from the message box this beeps twice

Code: Select all

if "3" is strictly a string then beep 2
It is just for integer and real that I don't get the "is strictly" to work.

Kind regards
Bernd

stam
Posts: 3072
Joined: Sun Jun 04, 2006 9:39 pm

Re: Whole numbers

Post by stam » Mon Sep 07, 2020 1:08 am

bn wrote:
Sun Sep 06, 2020 7:42 pm
As of LC 8.0 there is an "is strictly" operator.
value is strictly { nothing | a boolean | an integer | a real | a string | a binary string | an array }
Unfortunately I can not get it to work with integers. It probably reflects the internal state of LC or how it currently views value.
Maybe someone has more luck than I do.

Kind regards
hi bn -- i was unaware of the 'strictly' operator. Not sure why such an operator is needed, semantically it seems the same as 'is a'.
I found a bug report where LiveCode's Panos explains:
...
The ‘is strictly’ operators allow you to detect what the actual internal storage type of a value is.
Some things generate numbers which are stored as int32s but most will store them as doubles - arithmetic operators included.
I don’t know what the docs say about ‘is strictly an integer’ but the operators themselves are definitely doing as they
should so the docs might need some refinement :)

Mark

P.S. The ‘is strictly’ operators were not really added for general use as they are tied to internal mechanisms.
They were added to help with doing faithful export of values (lcVCS way back IIRC).
so basically the issue is that integers are stored internally as doubles...

bwmilby
Posts: 462
Joined: Wed Jun 07, 2017 5:37 am
Contact:

Re: Whole numbers

Post by bwmilby » Mon Sep 07, 2020 3:32 am

When you ask “is an integer” you are actually asking if the value can be coerced to an integer which is why 3.0 and “3” report true. When you ask “is strictly” then the engine looks at how the value is actually stored without an attempt to coerce the value to the type. (Essentially what Mark said.)

stam
Posts: 3072
Joined: Sun Jun 04, 2006 9:39 pm

Re: Whole numbers

Post by stam » Mon Sep 07, 2020 7:16 am

Except as mentioned, strictly always returns false regardless if the value is 3 or 3.0.
That is, as I understand it, because of the way the value is stored internally (quite possibly the integer is stored as a double and the rational as some other data type internally).

The logic of “coercion” is suspect; I wonder if this was devised to try and explain the aberrant behaviour, rather than truly how the engine works.

I cannot think of a single reason that would be useful... and it’s not how any other language I’m aware of tackles this?

PlaidFlannel
Posts: 43
Joined: Fri Aug 21, 2020 7:06 pm

Re: Whole numbers

Post by PlaidFlannel » Tue Sep 22, 2020 7:20 pm

I'm new to LiveCode (as of August), but in HyperCard, we often had to resort to gimmicks like this:

Code: Select all

function isInt n
   return n + 0 = trunc(n) 
end isInt
There are variations on this theme, but the idea is to force HyperCard (or LiveCode) to convert both comparands to its internal numerical form before doing the comparison. That catches oddball values like 0003.

Also, the function above does not necessarily behave well if the parameter is not numeric. You should add your own error handling as appropriate for your situation.

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10317
Joined: Wed May 06, 2009 2:28 pm

Re: Whole numbers

Post by dunbarx » Tue Sep 22, 2020 7:35 pm

PlaidFlannel.

HC and LC work exactly the same in all respects. Any, er, integer with leading zeros and/or trailing ones after a decimal point are seen as integers in both.

What does your function do that

Code: Select all

function isInt n
   return n is an integer
end isInt
does not?

Most of the above thread is about whether it matters. Programmatically it seems not. Aesthetically, well, that is another issue.

Craig

PlaidFlannel
Posts: 43
Joined: Fri Aug 21, 2020 7:06 pm

Re: Whole numbers

Post by PlaidFlannel » Sat Sep 26, 2020 12:41 am

User dunbarx is correct.

My memory of programming details from thirty years ago is obviously faulty. Maybe the gimmick of adding zero had been useful in some other untyped programming language of that era.

[NOTE: because this forum does not allow new members to use a decimal point in a post, I have substituted the bullet character • for a decimal point in the following text.]

Nevertheless, I was curious. Using an older Macintosh that is still capable of booting into System 9 (Mac OS 9•2•2 to be precise), I opened HyperCard 2•2 . I created a new stack with one card, which contained one button. The script of that button was:

Code: Select all

on mouseUp
   -- Expected result in HyperCard: 13, 13; 13, 13, 13, 5; 14, 14, 14 {and a runtime error here}
   
   -- Expected result in LiveCode: 13, 13; 13, 13, 13, 5; 14, 14, 14, 5,    0x369c     , 13980
    
   put "   " into sp3
   put "     " into sp5
   put "abcde" into alpha5
   put "12345" into num5
   put "0x369c" into hex4 -- or should that be hex6?
   
   put the number of chars of (sp3 & alpha5 & sp5)
   put sp3 & alpha5 & sp5 into string1
   put ", " & the number of chars of string1 after msg
   
   put "; " & the number of chars of (sp3 & num5 & sp5) after msg
   put sp3 & num5 & sp5 into string2
   put ", " & the number of chars of string2 after msg
   put ", " & the number of chars of (string2) after msg
   put ", " & the number of chars of (string2 + 0) after msg
   
   put "; " & the number of chars of (sp3 & hex4 & sp5) after msg
   put sp3 & hex4 & sp5 into string3
   put ", " & the number of chars of string3 after msg
   put ", " & the number of chars of (string3) after msg
   
   -- no hexadecimal constants in HyperTalk; this produces error:
   -- put ", " & the number of chars of (string3 + 0) after msg
   
   -- try it in LiveCode, where it should work
   -- put ", " & the number of chars of (string3 + 0) & ", " & string3  & ", " & (string3 + 0) after msg
   
end mouseUp
The only interesting result is that counting the characters in a string containing digits sometimes produces a different result after adding zero to the string.

A lesson to be learned is that there may be situations where it is important to know whether the internal representation of data in a HyperTalk or LiveCode variable or expression will be treated as a string or a number.

While I was in HyperCard, I confirmed one other expectation: comparisons of very long numeric strings can produce different results because of truncation. For example, in a HyperTalk script, these two 18-digit numbers are not equal:

3000000000000000000
3000000000000000001

while these two 19-digit numbers are equal:

30000000000000000000
30000000000000000001

Similarly, these two 15-digit numbers are not equal:

3000•00000000000
3000•00000000001

while these two 16-digit numbers are equal:

3000•000000000000
3000•000000000001

These results are the same whether the code contains the value as a number (unquoted string of digits) or as a quoted string.

Post Reply