Jump to content

Test integerness: Difference between revisions

→‎{{header|REXX}}: added version 2 and 3.
(add Perl solution)
(→‎{{header|REXX}}: added version 2 and 3.)
Line 144:
 
=={{header|REXX}}==
===version 1===
<lang rexx>/* REXX ---------------------------------------------------------------
* 20.06.2014 Walter Pachl
Line 252 ⟶ 253:
j is not an integer (imaginary part is not zero)
0003-00.0j is an integer</pre>
 
===version 2===
This REXX version handles an exponent indicator of '''E''', '''D''', or '''Q''' (either lower or uppercase), and it also supports a trailing '''I''' or '''J''' imaginary indicator.
 
Due to the way REXX handles numbers, any number that can be expressed simply (without exponential notation) within '''numeric digits''' is considered an integer.
<br>Thus, with '''numeric digits 100''', a number such as '''1e101''' wouldn't be considered an integer (within the rules of REXX).
<lang rexx>/*REXX pgm tests if a # (possibly complex) is equivalent to an integer.*/
numeric digits 10000 /*be able to handle big integers.*/
parse arg #s /*get optional #s list from C.L. */
if #s='' then #s= '3.14 1.00000 33 999999999 99999999999 1e272 AA 0' ,
'1.000-3i 1.000-3.3i 4j 2.00000000+0j 0j 333 -1-i' ,
'1+i .00i j 0003-00.0j 1.2d1 12.3q7 +0003-00.0j +0j' ,
'-.3q+2 -0i +03.0e+01+0.00e+20j -030.0e-001+0.0e-020j'
/* [↑] use these #s for defaults*/
do j=1 for words(#s); ox=word(#s,j) /*obtain a word from the #s list.*/
parse upper var ox x /*get an uppercase version of OX.*/
x=translate(x, 'EEI', "QDJ") /*alt. exponent & imag indicator.*/
if right(x,1)=='I' then call tImag /*has the X number an imag. part?*/
if isInt(x) then say right(ox,40) " is an integer." /*yup. */
else say right(ox,40) " isn't an integer." /*nope.*/
end /*j*/ /* [↑] process each # in list. */
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────one-liner subroutines───────────────*/
isInt: return datatype(arg(1),'Whole') /*compact method to test integer.*/
isSign: arg ? 2; return ?=='+' |?=='-' /*concise method to test a sign. */
/*──────────────────────────────────TIMAG subroutine────────────────────*/
tImag: x=left(x, length(x)-1) /*strip the trailing I or J. */
if isInt(x) then do /*is what's remaining an integer?*/
if x\=0 then x=. /*what's remaining isn't = zero. */
return /*return to invoker either way. */
end /* [↑] handle simple imag. case.*/
if isSign(x) then x=substr(x,2) /*strip leading sign from X ? */
e=verify(x, .0123456789) /*find 1st char not a digit | dot*/
if e==0 then do; x=.; return; end /*Nothing? Then it's ¬ an integer*/
y=substr(x, e, 1) /*Y is the suspect character. */
if isSign(y) then do /*is suspect char a plus | minus?*/
z=substr(x, e+1) /*obtain the imaginary part of X.*/
x= left(x, e-1) /* " " real " " " */
if isInt(z) then if z=0 then return /*imag. is 0.*/
x=. /*imaginary part isn't zero. */
end /* [↑] end of imag. part of X. */
if y=='E' then do /*the real part of X has a power.*/
p=substr(x, e+1) /*obtain power of real part of X.*/
_= left(p, 1) /*obtain the possible sign of pow*/
if isSign(_) then p=substr(p, 2) /*strip the power sign*/
s=verify(p, '-+', "M") /*imaginary sep char. */
if s==0 then do; x=.; return; end /*No sign? Not integer*/
z=substr(p, s+1) /*get the imag. part. */
x= left(x, e+s) /* " " real " */
if isInt(z) then if z\=0 then x=. /*Not imag=0? Not int*/
end /* [↑] handle imag. */
return /*return to invoker. */</lang>
'''output''' using the default input:
<pre>
3.14 isn't an integer.
1.00000 is an integer.
33 is an integer.
999999999 is an integer.
99999999999 is an integer.
1e272 is an integer.
AA isn't an integer.
0 is an integer.
1.000-3i isn't an integer.
1.000-3.3i isn't an integer.
4j isn't an integer.
2.00000000+0j is an integer.
0j is an integer.
333 is an integer.
-1-i isn't an integer.
1+i isn't an integer.
.00i is an integer.
j isn't an integer.
0003-00.0j is an integer.
1.2d1 is an integer.
12.3q7 is an integer.
+0003-00.0j is an integer.
+0j is an integer.
-.3q+2 is an integer.
-0i is an integer.
+03.0e+01+0.00e+20j is an integer.
-030.0e-001+0.0e-020j is an integer.
</pre>
 
===version 3===
This REXX version is the same as the 2<sup>nd</sup> version, but it also supports multiple (abutted) unary operators.
 
I.E.: &nbsp; ++30e-1 &nbsp; - &nbsp; +0j
 
would be considered an integer &nbsp; (extra blanks were added to show the number with more clarity).
<lang rexx>/*REXX pgm tests if a # (possibly complex) is equivalent to an integer.*/
numeric digits 10000 /*be able to handle big integers.*/
unaB='++ -- -+ +-' /*list of unary operators. */
unaA='+ + - -' /*list of unary operators trans. */
parse arg #s /*get optional #s list from C.L. */
if #s='' then #s= '245+-00.0e-12i 245++++++0e+12j --3450d-1----0.0d-1j'
/* [↑] use these #s for defaults*/
do j=1 for words(#s); ox=word(#s,j) /*obtain a word from the #s list.*/
parse upper var ox x /*get an uppercase version of OX.*/
x=translate(x, 'EEJ', "QDI") /*alt. exponent & imag indicator?*/
 
do k=1 for words(unaB) /*process every possible unary op*/
_=word(unaB,k) /*unary operator to be changed. */
 
do while pos(_,x)\==0 /*keep changing 'til no more left*/
x=changestr(_, x, word(unaA,k)) /*reduce all uniry operators. */
end /*while*/
end /*k*/
 
if right(x,1)=='J' then call tImag /*has the X number an imag. part?*/
if isInt(x) then say right(ox,40) " is an integer." /*yup. */
else say right(ox,40) " isn't an integer." /*nope.*/
end /*j*/
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────one-liner subroutines───────────────*/
isInt: return datatype(arg(1),'Whole') /*compact method to test integer.*/
isSign: arg ? 2; return ?=='+' |?=='-' /*concise method to test a sign. */
/*──────────────────────────────────TIMAG subroutine────────────────────*/
tImag: x=left(x, length(x)-1) /*strip the trailing I or J. */
if isInt(x) then do /*is what's remaining an integer?*/
if x\=0 then x=. /*what's remaining isn't = zero. */
return /*return to invoker either way. */
end /* [↑] handle simple imag. case.*/
if isSign(x) then x=substr(x,2) /*strip leading sign from X ? */
e=verify(x, .0123456789) /*find 1st char not a digit | dot*/
if e==0 then do; x=.; return; end /*Nothing? Then it's ¬ an integer*/
y=substr(x, e, 1) /*Y is the suspect character. */
if isSign(y) then do /*is suspect char a plus | minus?*/
z=substr(x, e+1) /*obtain the imaginary part of X.*/
x= left(x, e-1) /* " " real " " " */
if isInt(z) then if z=0 then return /*imag. is 0.*/
x=. /*imaginary part isn't zero. */
end /* [↑] end of imag. part of X. */
if y=='E' then do /*the real part of X has a power.*/
p=substr(x, e+1) /*obtain power of real part of X.*/
_= left(p, 1) /*obtain the possible sign of pow*/
if isSign(_) then p=substr(p, 2) /*strip the power sign*/
s=verify(p, '-+', "M") /*imaginary sep char. */
if s==0 then do; x=.; return; end /*No sign? Not integer*/
z=substr(p, s+1) /*get the imag. part. */
x= left(x, e+s) /* " " real " */
if isInt(z) then if z\=0 then x=. /*Not imag=0? Not int*/
end /* [↑] handle imag. */
return /*return to invoker. */</lang>
'''output''' using the default input:
<pre>
245+-00.0e-12i is an integer.
245++++++0e+12j is an integer.
--3450d-1----0.0d-1j is an integer.
</pre>
 
=={{header|Tcl}}==
Cookies help us deliver our services. By using our services, you agree to our use of cookies.