Comment faire pour tester des entiers dans MATLAB?

j'écris un programme qui va calculer les factoriels des entiers. Cependant, la partie sur laquelle je suis coincé est si quelqu'un entre un non-entier tel que 1.3, je voudrais être en mesure de tester la saisie et l'affichage "The number you have entered is not an integer"

18
demandé sur Ryan 2011-03-22 22:12:35

7 réponses

Vous pouvez utiliser le mod fonction qui renvoie le reste après la division. Tous les nombres entiers sont divisibles par 1. Donc un bon test pour non-entier serait

integerTest=~mod(value,1);

renvoie 0 si value n'est pas un entier et 1 si c'est le cas. Vous pouvez alors l'utiliser comme une condition pour rejeter les entrées utilisateur non-integer.

27
répondu abcd 2011-03-22 19:55:38

Voici une autre variante (vous pouvez le voir utilisé dans ISIND fonction: edit isind.m):

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

Sur ma machine, il est plus rapide que les autres solutions proposées:

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

Horaires:

Elapsed time is 0.012253 seconds.
Elapsed time is 0.014201 seconds.
Elapsed time is 0.005665 seconds.
22
répondu Amro 2011-08-02 18:35:47

vous pouvez lancer la valeur à un entier et de nouveau à un double et vérifier le résultat par rapport à la valeur originale:

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

ans =

     0

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

ans =

     1

il est Intéressant de noter, approche de R. M. de L'utilisation du MOD court plus vite dans une boucle et l'approche de coulée ci-dessus court plus vite lorsque vectorisé:

>> 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
répondu b3. 2017-05-23 10:30:38

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

Vous pouvez ajouter d'autres contrôles, (comme pour la positivité) facilement.

édité en utilisant isinteger. Merci @SolarStatistics, Je n'avais pas remarqué qu'ils avaient ajouté cette fonctionnalité. Corrigé retour à la réponse originale de nouveau comme isinteger n'est pas appropriée (voir les commentaires ci-dessous).

2
répondu MatlabSorter 2013-04-16 20:39:48

en tant Que point par @nibot isinteger tests pour l'entrée en tant que TYPE entier. Au lieu de cela, vous pouvez vérifier pour voir si l'arrondi entrée renvoie la même valeur que entrée. par exemple:

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

par exemple

>> 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.')
>> 
0
répondu Azim 2011-03-22 19:56:24

je voulais juste souligner que les méthodes fournies testent toutes si l'entrée est un nombre entier gaussien, ce qui signifie que les parties réelles et imaginaires sont nombres entiers. Si vous devez vous préoccuper de la partie imaginaire, alors vous devez le traiter séparément.

Pour mes applications, les entrées avec les imaginaires des composants ne doit pas être considéré comme un entier valide, donc j'ai ceci:

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

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

l'appel en boucle est un peu plus lent surtout à cause de la fonction overhead. En remplaçant l'expression arithmétique par ~mod(dataInput, 1), il sera seulement 50% plus rapide que le code qui vérifie les parties imaginaires.

0
répondu Setsu 2015-02-05 20:00:51

Par double la commande, vous ne pouvez pas obtenir la réponse correcte:

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

floor,round,... ont des problèmes avec de tels cas:

floor(22/22)==21.99999999999999999999999999999999999/22

mais mod semble peut distinguer 22/22 et 21.99999999999999999999999999999999999/22:

>> mod(22,22)
ans =
     0
>> (21.99999999999999999999999999999999999/22)
ans =
     1
-1
répondu Hossein Tavakoli 2014-02-18 06:09:30