wake-up-neo.net

Wie teste ich in MATLAB auf ganze Zahlen?

Ich schreibe ein Programm, das Fakultäten für ganze Zahlen berechnet. Wenn ich jedoch eine nicht ganzzahlige Zahl wie 1.3 eingebe, möchte ich die Eingabe testen und anzeigen lassen. "The number you have entered is not an integer"

18
Ryan

Sie können die Funktion mod verwenden, die den Rest nach der Division zurückgibt. Alle Ganzzahlen sind durch 1 teilbar. Ein guter Test für nicht ganzzahlige Werte wäre also 

integerTest=~mod(value,1);

Dies gibt 0 zurück, wenn value keine Ganzzahl ist, und 1, falls dies der Fall ist. Sie können dies dann als Bedingung verwenden, um nicht ganzzahlige Benutzereingaben abzulehnen.

27
abcd

Hier ist eine weitere Variante (Sie können sehen, dass sie in ISIND function verwendet wird: edit isind.m):

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

Auf meiner Maschine ist es schneller als die anderen vorgeschlagenen Lösungen:

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

Zeiten:

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

Sie können den Wert in eine Ganzzahl und zurück in ein Double umwandeln und das Ergebnis mit dem ursprünglichen Wert vergleichen:

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

 ans = 

 0 

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

 Ans = 

 1 

Interessanterweise läuft der Ansatz von R.M. der Verwendung von MOD in einer Schleife schneller und der obige Casting-Ansatz läuft schneller, wenn er vektorisiert wird:

 >> x = Rand (100000, 1); 
 >> tic; für ii = 1: 100000; mod (x (ii), 1); Ende; toc; 
 Verstrichene Zeit beträgt 0.018380 Sekunden .
 >> tic; für ii = 1: 100000; x(ii) == double (uint64 (x (ii))); Ende; toc; 
 Die verstrichene Zeit beträgt 0,383020 Sekunden 
 >> tic; ~ mod (x, 1); toc; 
 Die verstrichene Zeit beträgt 0,005299 Sekunden .
 >> tic; x == double (uint64 (x)); toc; 
 Die verstrichene Zeit beträgt 0,002971 Sekunden .
4
b3.

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

Sie können auch problemlos andere Schecks (z. B. für Positivität) hinzufügen.

Bearbeitet mit isinteger. Danke @SolarStatistics, ich hatte nicht bemerkt, dass sie diese Funktionalität hinzugefügt haben. Zurück zur ursprünglichen Antwort geändert, da isinteger nicht geeignet ist (siehe Kommentare unten).

2
MatlabSorter

Wie @nibot isinteger zeigt, prüft die Eingabe als Ganzzahl TYPE. Stattdessen können Sie prüfen, ob die Rundung input denselben Wert wie input liefert. z.B:

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

zum Beispiel

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

Ich wollte nur darauf hinweisen, dass die bereitgestellten Methoden alle prüfen, ob die Eingabe eine Gaußsche Ganzzahl ist, was bedeutet, dass die Real- und Imaginärteile beide Ganzzahlen sind. Wenn Sie sich um den Imaginärteil kümmern müssen, müssen Sie ihn separat behandeln.

Für meine Anwendungen sollten Eingaben mit imaginären Komponenten nicht als gültige Ganzzahl betrachtet werden, daher habe ich Folgendes:

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

Mit den Tests von 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.

Der Anruf in der Schleife ist etwas langsamer, hauptsächlich aufgrund des Funktionsaufwands. Wenn Sie den arithmetischen Ausdruck durch ~ mod (dataInput, 1) ersetzen, wird er nur 50% schneller als der Code, der auf imaginäre Teile prüft.

0
Setsu