xlabel - ¿Cómo pruebo los enteros en MATLAB?
title graphics matlab (7)
Aquí hay otra variación (puede ver que se usa en la función ISIND : edit isind.m
):
integerTest = ( x == floor(x) );
En mi máquina, es más rápido que las otras soluciones propuestas:
%# 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) )
Tiempos:
Elapsed time is 0.012253 seconds.
Elapsed time is 0.014201 seconds.
Elapsed time is 0.005665 seconds.
Estoy escribiendo un programa que calculará factoriales de enteros. Sin embargo, la parte en la que estoy bloqueado es si alguien ingresa un número no entero como 1.3
, me gustaría poder probar la entrada y mostrar "The number you have entered is not an integer"
Como lo indica @nibot isinteger prueba la entrada como un TIPO entero. En su lugar, puede verificar si la entrada de redondeo devuelve el mismo valor que la entrada . p.ej:
assert(abs(round(input)-input))<eps*2,''That number is not an integer.'')
por ejemplo
>> 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.'')
>>
Por double
comando, no puede obtener la respuesta correcta:
>> double(uint64(21/22))
ans =
1
>> double(uint64(22/22))
ans =
1
También floor
, round
, ... tenemos problema con tales casos:
floor(22/22)==21.99999999999999999999999999999999999/22
pero parece que el mod
puede distinguir 21.99999999999999999999999999999999999/22
y 21.99999999999999999999999999999999999/22
:
>> mod(22,22)
ans =
0
>> (21.99999999999999999999999999999999999/22)
ans =
1
Puede convertir el valor en un entero y volver al doble y comparar el resultado con el valor original:
>> x = 1.3; >> x == double(uint64(x)) ans = 0 >> x = 2; >> x == double(uint64(x)) ans = 1
Curiosamente, el enfoque de RM de usar MOD se ejecuta más rápido en un bucle y el enfoque de conversión anterior se ejecuta más rápido cuando se vectoriza:
>> 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.
Puede usar la función mod
, que devuelve el resto después de la división. Todos los enteros son divisibles por 1
. Así que una buena prueba para no-entero sería
integerTest=~mod(value,1);
Esto devuelve 0
si el value
no es un entero y 1
si lo es. Luego puede usar esto como un condicional para rechazar entradas de usuarios no enteros.
Solo quería señalar que todos los métodos proporcionados comprueban si la entrada es un entero gaussiano , lo que significa que las partes real e imaginaria son ambas enteras. Si necesita preocuparse por la parte imaginaria, debe tratarla por separado.
Para mis aplicaciones, las entradas con componentes imaginarios no deberían considerarse un entero válido, por lo que tengo esto:
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
Usando las pruebas de b3.''s:
>> 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.
La llamada en bucle es bastante más lenta debido principalmente a la sobrecarga de la función. Reemplazar la expresión aritmética con ~ mod (dataInput, 1) hará que sea un 50% más rápido que el código que verifica las partes imaginarias.
assert(isnumeric(input) && round(input) == input, ''That number is not an integer.'')
Usted podría agregar otros controles, (como por positividad) fácilmente también.
Editado utilizando isinteger
. Gracias a @SolarStatistics
, no había notado que agregaron esta funcionalidad. Editado nuevamente a la respuesta original, ya que isinteger
no es apropiado (vea los comentarios a continuación).