Jump to content

Check if integer


Shihan Feiri
 Share

You are about to reply to a thread that has been inactive for 1446 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

integer isInteger( string message ){    return (float)message == (float)((integer)message);}default{    state_entry()    {        llOwnerSay( (string)isInteger("-7"));        llOwnerSay( (string)isInteger("-7.02"));    }}

Here is a routine: "isInteger" that can say if a string is float formatted or not.

If not it is expected to have integer format

The string can always be cast to an integer no matter what it is

It should answer the question in the OP:)

Link to comment
Share on other sites

Or try this ...

 

list integers = ["-","0","1","2","3","4","5","6","7","8","9"];default{     //more stuff goes here ....    listen (integer channel, string name, key id, string msg)    {        integer Flag = TRUE;        integer i;        for (i=0;i<llStringLength(msg);++i)        {            if (( !~llListFindList(integers,[llGetSubString(msg,i,i)] )) || ((llGetSubString(msg,i,i) == "-") && (i != 0)))            {                llSay(0,"This message contains a non-integer.");                Flag = FALSE;            }                    }        if (Flag)        {            llSay(0,"The message in the Text Box is an integer = " + (string) msg);        }    }}

 

 ETA: Modified, per Dora, to recognize negative integers. 

 

    

 

Link to comment
Share on other sites


Dora Gustafson wrote:

This is
fairly
tight,
but does not include
negative
integers.

It's a good
thing
that
the OP
is so
vague,
It allows
many interpretations:)

Good point. I'll pop back up there and accomodate negative integers.  :smileyhappy:

Link to comment
Share on other sites

Hehe .... OK... I wouldn't normally put a redundant + sign in front of a positive integer, but for completeness, do this ...

list integers = ["+","-","0","1","2","3","4","5","6","7","8","9"];integer gLisn;default{        touch_start(integer num)    {        llListenRemove(gLisn);        gLisn = llListen(91,"","","");        llTextBox(llDetectedKey(0),"Type an integer and click \"Submit\".",91);    }            listen (integer channel, string name, key id, string msg)    {        llListenRemove(gLisn);        integer Flag = TRUE;        integer i;        for (i=0;i<llStringLength(msg);++i)        {            if (llGetSubString(msg,i,i) == llUnescapeURL("%0A"))            {                if (i == llStringLength(msg) -1)                {                    msg = llGetSubString(msg, 0,-2);                    llSay(0,"Final carriage return removed.");                 }                else                {                    llSay(0,"This message contains a non-integer.");                    Flag = FALSE;                }            }            else if (( !~llListFindList(integers,[llGetSubString(msg,i,i)] )) || ((~llListFindList(["+","-"],[llGetSubString(msg,i,i)])) && (i != 0)))            {                llSay(0,"This message contains a non-integer.");                Flag = FALSE;            }                    }        if (Flag)        {            llSay(0,"The message in the Text Box is an integer = " + (string) msg);        }    }}

 

This time, I anticipated your next challenge, Dora.  If someone types an integer and then hits the ENTER key before clicking the Submit button in the text box, this version will ignore the carriage return and still recognize the string as an integer. This is getting ridiculously clunky now, but it works.  :smileyhappy:

Edit: Cleaned up code.  A little less clunky.

 

Link to comment
Share on other sites

How about this?

linteger gLisn;

default
{    
    touch_start(integer num)
    {
      gLisn = llListen(91,"","","");
      llTextBox(llDetectedKey(0),"Type an integer and click \"Submit\".",91);
    }        

    listen (integer channel, string name, key id, string msg)
    {
      integer i;
      string ch;
      integer n = llStringLength(msg);
llListenRemove(gLisn);
      for(i=0; i<n; i++)  
        {
        ch = llGetSubString(msg,i,i);
        if(!(integer)ch && ch != "0")
          if(i) jump break;
          else if(ch != "+" && ch != "-" && ch != " ")
            jump break1;
        }
      @break;
      @break1;
      if(i != n)
        llSay(0,"This message contains a non-integer.");
      else
        llSay(0,"The message in the Text Box is an integer = " + (string) msg);
    }
}

 

 

Link to comment
Share on other sites

@Ela: I admire your sharp logic and different approach, not just in this case but also back in time.
@Rolig: It is clunky in LSL. It is something that is best done on a lower programming level.
Actually the integer cast does a lot of it, but it doesn't reveal if the text could be cast to another type.
Integer cast is very robust too, I don't think any string can make it throw an error.
If the string is not starting with a number it will simply return zero.

Personally I would never resort to a string testing like those outlined by you, though it is fun to make one.:)
If I want an integer from a textbox I would simply cast the string to an integer and test that against what integers I can use in the program.

Link to comment
Share on other sites

I agree, Dora.  This was fun to approach as a puzzle but my script was overkill for anything I'd put into a working device.  We have somehow gotten out of the habit of doing puzzles here recently, so thank you for the mild push that goaded me into posting this one.  Ela's approach is much more practical. 

I'm posting as my alt today, BTW.   LL's saboteurs are messing with the forums, so the real me is having a hard time logging in.

Link to comment
Share on other sites

I'm finally able to log in as myself.  In my hours off, though, I have been listening to a far-off voice in the void that suggested yet another solution.....

uIsSimpleInteger( vStrTxt ){	vStrTxt = llList2String( llParseString2list( vStrTxt, [" "], [] ), 0 );	if (~llListFindList( ["+", "-"], [llGetSubString( vStrTxt, 0, 0 )] )){		vStrTxt = llGetSubString( vStrTxt, 1, -1 );	}	return (string)((integer)vStrTxt) == vStrTxt;}//-- fails on hexadecimal and scientific notation

 This approach resembles the one I posted earlier, but is more compact, since it doesn't step through the message string one character at a time but grabs the whole banana in one bite.  It doesn't address the trailing carriage return challange, but that's easy enough to tag on.

Link to comment
Share on other sites

  • 6 years later...

Here's my goto method that I threw together after getting tired of typing the same cast tests along with sorting out signs and stuff over and over.

It can test for signed and unsigned integers and/or floats.  You get to specify what type of numbers you want it to accept or reject on the fly.

 

It checks each character of a string to see if:

1.  It can be cast into an integer that matches itself.  if ((string)((integer)string) == string)

2.  It checks for periods and minus signs....if it hits one it sets a bit.

3.  It checks the bit to make sure we don't already have a . or - registered in the string.  If so it breaks and returns 0.

4.  If it comes across a string that has just a minus or period alone but no numbers, it returns 0.

5.  It checks to make sure the minus sign (if present) is the first character in the string, if not it returns zero.

6.  It takes the three simple bits obtained above and formats the return in a way where you can easily specify the type of number you're checking for (negative or unsigned [positive] integers and/or floats).

The function returns 0 if it hits a character in the string that's not a minus, period, or 0-9, otherwise it returns one of these integers...
141, 277, 166, or 326.  This makes it easy to simply check a single bit to see if your string passes your specified test.

 

Simply copy the function below into the header of your script.  From then on you can use it throughout your code in the form of isNumber(string)&bit.

//Is a given 'string' representing an integer or float?
//Example tests:  
//if (isNumber(string) & 1) to test if it's an integer of either sign.
//if (isNumber(string) & 2) to test if it's a float of either sign.
//if (isNumber(string) & 4) to test if it's either a float or an integer of either sign.
//if (isNumber(string) & 8) to test for a positive integer.
//if (isNumber(string) & 16) to test for a negative integer.
//if (isNumber(string) & 32) to test for a positive float.
//if (isNumber(string) & 64) to test for a negative float.
//if (isNumber(string) & 128) to test for a positve integer or float.
//if (isNumber(string) & 256) to test for a negative integer or float.
integer isNumber(string input)
{
    integer i = 0;
    integer c = 0;
    integer l = llStringLength(input);
    string s;
    while (c < l) {
        s = llGetSubString(input,c,c);
        if ( ( (string)((integer)s) == s ) || ( s == "-" ) || ( s == "." ) ) {
            
            //Test for possible negative integers.
            if (s == "-") {
                if (~i & 4) i = 4|i; //If it's not already tagged, flip the 3rd bit if it's a negative sign.
                else { i = 0; return i; } //If we come across more than one negative in the string fail.
            }
            
            else if (s == ".") {
                if (~i & 2) i = 2|i; //If it's not already tagged, flip the 2nd bit if it's a period.
                else { i = 0; return i; } //If we come across more than one period in the string fail.
            }
            
            else i = 1|i; //Flip the first bit if it otherwise passed the ((string)((integer)string) == string) test.  
                          //AFAIK, thats just 0 - 9 in lsl.
                
            ++c;
        } else {
            return 0;
        }
    }
    
    //if there's a minus sign in here somewhere, make sure it's the first character in the string.
    if ( (i & 4) && (llGetSubString(input,0,0) != "-") ) { i = 0; return i; }
    
    //Now take our three bits and expand them so the user can have lots of test switches avilable.
    if (i == 1)      i = 141; //010001101  A positive integer.
    else if (i == 5) i = 277; //100010101  A negative integer.
    else if (i == 3) i = 166; //010100110  A positive float.
    else if (i == 7) i = 326; //101000110  A negative float.
    else if (i == (2|4|6)) i = 0;  //just got periods and/or negative signs but no numbers....so //000

    return i;
}

 

Edited by Credo Rolland
Fixed some typos in the comments, previous version should work fine but this one has cleaner 'comments'.
  • Thanks 1
Link to comment
Share on other sites

  • 1 year later...

another suggestion to determine if a string or number.  Once you determine if it is a number then you can truncate or round to an integer afterwards.

 

integer isNum(string s)
{
    s = llStringTrim(s, STRING_TRIM);
    integer l = llStringLength(s)-1;
    float Si = (float)s;
    llOwnerSay(s + ":" + llGetSubString((string)Si,0,l));
    
    if(s == llGetSubString((string)Si,0,l))
    {
        return TRUE;
    } else {
        return FALSE;
    }
}    

default
{
touch_start(integer i)
    {
        if (isNum("-1"))
        {
            llOwnerSay("TRUE");
        }
        else
        {
            llOwnerSay("FALSE");
        }
            
    }
}

Edited by MagiKesh Tumim
Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 1446 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...