Подтвердить что ты не робот

Как проверить для целых чисел в MATLAB?

Я пишу программу, которая будет вычислять факториалы целых чисел. Тем не менее, часть, на которую я застрял, - это если кто-то вводит нецелое число, например 1.3, я бы хотел проверить вход и отображение "The number you have entered is not an integer"

4b9b3361

Ответ 1

Вы можете использовать функцию mod, которая возвращает остаток после деления. Все целые числа делятся на 1. Таким образом, хороший тест для нецелого числа будет

integerTest=~mod(value,1);

Это возвращает 0, если value не является целым числом и 1, если оно есть. Затем вы можете использовать это как условие для отклонения нецелевых пользовательских входов.

Ответ 2

Вот еще один вариант (вы можете видеть, что он используется в ISIND: edit isind.m):

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

На моей машине это быстрее, чем другие предлагаемые решения:

%# 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) )

Тайминги:

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

Ответ 3

Вы можете присвоить значение целому числу и вернуться к двойному и проверить результат на исходное значение:

>> x = 1.3;
>> x == double(uint64(x))

ans =

     0

>> x = 2;
>> x == double(uint64(x))

ans =

     1

Интересно, R.M. подход использования MOD работает быстрее в цикле, и вышеупомянутый подход к литью выполняется быстрее при векторизации:

>> 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.

Ответ 4

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

Вы также можете легко добавить другие проверки (например, для позитивности).

Отредактировано с помощью isinteger. Спасибо @SolarStatistics, я не заметил, что они добавили эту функциональность. Отредактировано обратно к исходному ответу снова, поскольку isinteger не подходит (см. Комментарии ниже).

Ответ 5

Как указано в тестах @nibot isinteger для ввода как целочисленного ТИПА. Вместо этого вы можете проверить, возвращает ли округление входное значение того же значения, что и вход. например:

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

например

>> 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.')
>> 

Ответ 6

Я просто хотел указать, что предоставленные методы проверяют, является ли вход гауссовским целым, что означает, что действительная и мнимая части оба целые числа. Если вам нужно заботиться о воображаемой части, вам нужно разобраться с ней отдельно.

Для моих приложений входные данные с мнимыми компонентами не должны считаться действительным целым числом, поэтому у меня есть следующее:

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

Использование b3. Тесты:

>> 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.

Замедленный вызов довольно медленный, в основном из-за служебных функций. Замена арифметического выражения на ~ mod (dataInput, 1) сделает его только на 50% быстрее, чем код, который проверяет мнимые части.

Ответ 7

В команде double вы не можете получить правильный ответ:

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

также floor, round,... имеют проблему с такими случаями:

floor(22/22)==21.99999999999999999999999999999999999/22

но mod может различать 22/22 и 21.99999999999999999999999999999999999/22:

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