if语句只识别某些整数:MATLAB

时间:2017-04-12 05:08:49

标签: matlab if-statement

如果我的if变量为digitToFind,则以下5语句才能正常运行,否则会被忽略。

if(digitToFind == R)
    digitToFindFreq = digitToFindFreq + 1;
end

该程序用于计算给定整数中的位数,并查找用户选择的一个特定数字的频率。

示例:123445;位数是6,频率4是2

digitToFindFreq = 0;
    numOfDigits = 0;

integerInput = input('Enter an integer: ');
while(integerInput ~= round(integerInput))
    fprintf('Invalid input. Try again!\n');
    integerInput = input('Enter an integer: ');
end
digitToFind = input('Enter a digit number to find (0 to 9): ');
while(digitToFind < 0 || digitToFind > 9 || digitToFind ~= round(digitToFind))
    fprintf('Invalid input. Try again!\n');
    digitToFind = input('Enter a digit number to find (0 to 9): ');
end


if(integerInput == 0 && digitToFind ~= 0)
    numOfDigits = 1;
    digitToFindFreq = 0;
elseif(integerInput == 0 && digitToFind == 0)
    numOfDigits = 1;
    digitToFindFreq = 1;
end


while(integerInput >= 1)
    integerInput = integerInput/10;

    X = integerInput - fix(integerInput);
    R = 10*X;

    if(digitToFind == R)
        digitToFindFreq = digitToFindFreq + 1;
    end
integerInput = integerInput - X;
numOfDigits = numOfDigits + 1;
end


fprintf('\nNumber of digits: %d, Digit to find frequency: %d\n',numOfDigits,digitToFindFreq);

我之前从未遇到过这样的问题。它必须是我失踪的小东西,因为否则程序正常工作。

1 个答案:

答案 0 :(得分:0)

这可能是浮点数的一个问题,当你除以并乘以10并减去余数时,你的值不是一个整数。因此,直接==测试可能会失败。

1.0000000000000001 == 1 % False

您应该用以下代码替换您的测试:

if(abs(digitToFind - R) < 0.1) % the digit must be close to digitToFind
    digitToFindFreq = digitToFindFreq + 1;
end

或使用字符串:

integerInput = num2str(integerInput);
digitToFind = num2str(digitToFind);
while length(integerInput) > 0
    R = integerInput(end);
    integerInput = integerInput(1:end-1);

    if strcmp(digitToFind, R)
        digitToFindFreq = digitToFindFreq + 1;
    end
    integerInput = integerInput - X;
    numOfDigits = numOfDigits + 1;
end

但实际上,不要使用这些方法。您没有利用Matlab的内置索引来为您完成所有艰苦的工作。我已经重写了整个代码,因此您还可以看到如何使用字符串而不是整数进行验证检查。注意下面的方法,我已经改变了输入类型,因此不需要num2str,你的整数可以更大。

% include your error checking here, but based on strings
integerInput = '.';
digitToFind = '.';
% Check all characters in integerInput are digits 0-9, so integer
while ~(all(integerInput >= '0') && all(integerInput <= '9')) 
    % Include the 's' qualifier to convert input directly to string, allows
    % for much longer integers than using num2str() later on
    integerInput = input('Enter an integer: ', 's');
end
% Check digitToFind is 0-9, and only 1 character
while ~(all(digitToFind >= '0') && all(digitToFind <= '9')) || length(digitToFind) ~= 1
    digitToFind = input('Enter a digit number to find (0 to 9): ', 's');
end
% use logical indexing to find vector of 1s and 0s in the positions where 
% integerInput(i) = digitToFind. Then count the number of non-zero elements
% using nnz (in built function). No need for your edge-case 0 checks either.
numOfDigits = length(integerInput);
digitToFindFreq = nnz(integerInput == digitToFind);

¹关于最大输入尺寸的说明

intmax('uint64') = 18446744073709551615是Matlab可以处理的最大(无符号)整数。请注意,realmax = 1.7977e+308 显着更大!对于您的应用程序,我认为允许大于约20位的输入是合乎需要的,因此将它们表示为整数将会出现问题。 这可能是您遇到测试问题的另一个原因,因为超出intmax限制的任何内容都必须存储为浮点数(实数),而不是整数!

通过将's'标志与input命令一起使用,输入数字不会被计算为整数,而是直接转换为字符串。字符串变量的最大长度为only dependent on your computer's memory,因此可能非常大!例如,我可以在内存不足之前创建900,000,000个元素字符串(1.8 GB)。

编辑:

在上面,为了检查数字在0-9范围内,我正在使用它们的ASCII值是连续的这一事实,因为这是被比较的。您还可以使用内置isstrprop

while ~(all(isstrprop(integerInput, 'digit'))) 
    ...