# How do I test for integers in MATLAB?

I'm writing a program that will calculate factorials of integers. However, the part I'm stuck on is if someone enters a non-integer such as 1.3, I'd like to be able to test the input and display "The number you have entered is not an integer"

## Answers

You can use the mod function, which returns the remainder after division. All integers are divisible by 1. So a good test for non-integer would be

integerTest=~mod(value,1);

This returns 0 if value is not an integer and 1 if it is. You can then use this as a conditional to reject non-integer user inputs.

Here is another variation (you can see it being used in ISIND function: edit isind.m):

integerTest = ( x == floor(x) );

On my machine, it is faster than the other proposed solutions:

%# create a vector of doubles, containing integers and non-integers x = (1:100000)'; %' idx = ( rand(size(x)) < 0.5 ); x(idx) = x(idx) + rand(sum(idx),1); %# test for integers tic, q1 = ~mod(x, 1); toc tic, q2 = x==double(uint64(x)); toc tic, q3 = x==floor(x); toc %# compare results assert( isequal(q1,q2,q3) )

Timings:

Elapsed time is 0.012253 seconds. Elapsed time is 0.014201 seconds. Elapsed time is 0.005665 seconds.

You can cast the value to an integer and back to a double and check the result against the original value:

>> x = 1.3; >> x == double(uint64(x)) ans = 0 >> x = 2; >> x == double(uint64(x)) ans = 1

Interestingly, R.M.'s approach of using MOD runs faster in a loop and the above casting approach runs faster when vectorized:

>> x = rand(100000, 1); >> tic; for ii = 1:100000; ~mod(x(ii), 1); end; toc; Elapsed time is 0.018380 seconds. >> tic; for ii = 1:100000; x(ii) == double(uint64(x(ii))); end; toc; Elapsed time is 0.383020 seconds. >> tic; ~mod(x, 1); toc; Elapsed time is 0.005299 seconds. >> tic; x == double(uint64(x)); toc; Elapsed time is 0.002971 seconds.

assert(isnumeric(input) && round(input) == input, 'That number is not an integer.')

You could add other checks, (like for positivity) easily as well.

Edited using isinteger. Thanks @SolarStatistics, I hadn't noticed they added this functionality. Edited back to original answer again as isinteger isn't appropriate (see comments below).

As point out by @nibot *isinteger* tests for the input as an integer TYPE. Instead you could check to see if rounding *input* returns the same value as *input*. eg:

assert(abs(round(input)-input))<eps*2,'That number is not an integer.')

for example

>> input=1.3; >> assert(abs(round(input)-input)<eps*2,'That number is not an integer.') ??? That number is not an integer. >> input=3; >> assert(abs(round(input)-input)<eps*2,'That number is not an integer.') >>

I just wanted to point out that the provided methods all test for whether the input is a *Gaussian integer*, meaning that the real and imaginary parts are **both** integers. If you need to care about the imaginary part then you need to deal with it separately.

For my applications, inputs with imaginary components shouldn't be considered a valid integer, so I have this:

function boolResult = fnIsInteger(input) %validate input if isempty(input) error('Input cannot be empty') elseif ~isnumeric(input) error('Input must be numeric') end boolResult = (imag(input) == 0) & (round(input) == input); end

Using b3.'s tests:

>> x = rand(100000, 1); >> tic; for ii = 1:100000; ~mod(x(ii), 1); end; toc; Elapsed time is 0.003960 seconds. >> tic; for ii = 1:100000; fnIsInteger(x(ii)); end; toc; Elapsed time is 0.217397 seconds. >> tic; ~mod(x, 1); toc; Elapsed time is 0.000967 seconds. >> tic; fnIsInteger(x); toc; Elapsed time is 0.003195 seconds.

The looped call is quite a bit slower mostly due to the function overhead. Replacing the arithmetic expression with ~mod(dataInput, 1) will make it only 50% faster than the code that checks for imaginary parts.

By double command, you cannot get the correct answer:

>> double(uint64(21/22)) ans = 1 >> double(uint64(22/22)) ans = 1

also floor,round,... have problem with such cases:

floor(22/22)==21.99999999999999999999999999999999999/22

but mod seems can distinguish 22/22 and 21.99999999999999999999999999999999999/22:

>> mod(22,22) ans = 0 >> (21.99999999999999999999999999999999999/22) ans = 1