How to detect if string data is number and integer in COS ?

Good day,

 

I would like to know how to detect in Caché ObjectScript if data saved in string is number and furthermore, if it's type is integer.


I maybe found a solution:
 

set value = "44.2d3"

try{
     set status = $INUMBER(value,"")
     if ('$FIND(+value,".")){
          w "your variable: '"_value_"' is number and integer"
     }else{
          w "variable is number but no integer"
     }
}catch(e){
     w "variable is not number" 
}



But I don't know how to do it correctly or if there exist better solution in COS (or maybe my solution is incorrect).

 

Thanks in advance for answers.

  • 0
  • 0
  • 643
  • 7
  • 3

Answers

If +value=value

This classic code is good for checking if the value is canonical number, while the term number can be interpreted in some other ways, e.g. a number in scientific format, double precision number, etc. Caché has a set of out-of-the-box functions to perform some of these checks, e.g. $isvalidnum, $isvaliddouble, $number, $normalize.

So, the answer depends on topic starter's conditions.

E.g., if I need to check if a number is a numlit (scientific numbers and numbers with starting zeroes are allowed), I'd use `$isvalidnum(x)`. Addition check on being integer (an intlit) can look like: `$isvalidnum(x)&&(+x\1=+x)`. Here are some testing results: 

USER> w !,?6,"Is number?",?20,"Is integer?",?35,"Is canonic?"
USER> for x="001a","002",0,1,"-1.2","+1.3","1E3" w !,x,?10," ",$isvalidnum(x),?20," ",$isvalidnum(x)&&(+x\1=+x),?35,x=+x
 
      Is number?    Is integer?    Is canonic?
001a       0         0             0
002        1         1             0
0          1         1             1
1          1         1             1
-1.2       1         0             1
+1.3       1         0             0
1E3        1         1             0

In other conditions I'd write another code. There is no universal answer to topic starter's question.

P.S. As to "Annotated MUMPS Standard" (http://71.174.62.16/Demo/AnnoStd):
An intlit is not necessarily a canonic representation of a number.

numlit is not necessarily a canonic representation of a number.

The reduction to a canonical numeric representation involves (colloquially) the removal of any redundant leading and trailing zeroes, the conversion of exponentionential notation to "mantissa only" notation, and the reduction of any leading plus (+) and minus (-) signs to at most one leading minus sign (see also Numeric interpretation of data).

 

Well, that's an interesting one.

One way to check whether the value of a string is a number is:

   If +value=value

which will work in most cases.

However, when the value of a string is something like "1E12345", you'd get an error (<MAXNUMBER>), because "exponential notation" is assumed. But in all other cases, that would work.

 

Similarly:

   If +value?1.N

Would get close to determining that a value is an integer, but "00000123" would also match that pattern, so

   If value?1.N,+value=value

would do the trick in this case.

 

Hope this helps

The oldest and most simple and fastest integer check is
if value\1=+value

\1 strips trailing decimals,  + strips leading 0

; just pure integer arithmetics no string checks

 


Are you sure that this will work?

USER > set number = "21d20"

USER > if (number\1 = +number) { w "number and integer" } else { w "not number and not integer" }

will output that it is "number and integer", because number\1 will turn string "21d20" to "21" as a result. 
Moreover +number will result from "21d20" to "21" ... and will tell that really 21 equals 21 ... but "21d20" is not number

You are right. The check for pure number got lost

if  +number=number  has to precede 

so the combined is  if  +number=number,number\1=+number

I believe that would be equal to just 

if number\1=number

This is a matter of interpretation.
If you also allow leading 0 for integers   (eg. 00123) then you need to normalize it.

But 

if  +number=number,number\1=+number

doesn't allow leading zeroes either.

Comments

set number = "1234"
write number?.N // 1, so it's integer.

set number = "44.2d3"
write number?.N // 0, so it's float, double or whatever data type with precison.

You can read more about Pattern Matching here.