How can I make the program count the number of decimals of an inputted amount

3 visualizaciones (últimos 30 días)
I have this code:
withdrawAmount = input ('Enter amount to Withdraw ');
.
.
.
.
.
Is there anyway the program could count the number of decimals entered for "withdrawAmount"
because i want to be able to use an if statement, saying if the entered amount has more than 2 decimal places, disp('invalid')

Respuesta aceptada

Walter Roberson
Walter Roberson el 10 de Dic. de 2021
withdrawAmount = input ('Enter amount to Withdraw ');
Is there anyway the program could count the number of decimals entered for "withdrawAmount"
Have a look at this:
withdrawAmount = 0.10
withdrawAmount = 0.1000
S = sprintf('%.99g', withdrawAmount)
S = '0.1000000000000000055511151231257827021181583404541015625'
length(S)
ans = 57
So the number of decimals entered was (57 - length('0.')) --> 55
Can you prove otherwise? NO. The user might have chosen to enter that long string of digits, and the binary value stored in withdrawAmount would be exactly the same.
Furthermore, you used input() . The user might have chosen to respond with (for example)
1/3
Now how many digits did they enter?
Remember that input() with no 's' option executes whatever the user entered as a command . And if the results are floating point, then they are stored in IEEE 754 double precision binary, which does not store values in base 10. You are completely unable to tell whether the user entered 0.1 or 0.10 or 0.10000 or 1/10 when you use input() without the 's' option.
Moral of the story: If you use input() and you need to validate something about the form that the user entered the number, then you need to use the 's' option.
  23 comentarios
Walter Roberson
Walter Roberson el 13 de Dic. de 2021
Editada: Walter Roberson el 13 de Dic. de 2021
function posnum = getPositiveNumber()
prompts = {'please enter a numeric amount : ',
'please enter a positive value : ',
'please limit your amount to 2 decimal places : '};
prompt_num = 1;
while true
prompt = prompts{prompt_num};
p = strtrim(input(prompt, 's'));
if ~isempty(regexp(p, '\.[0-9]{3,}'))
prompt_num = 3;
continue;
end
if ~isempty(regexp(p, '^-'))
prompt_num = 2;
continue;
end
vetted = regexp(p, '^([0-9]+(\.[0-9]{0,2})?$)|^\.[0-9]{1,2}$', 'match');
if isempty(vetted)
prompt_num = 1;
continue;
end
trial_num = str2double(vetted);
if isnan(trial_num)
fprintf('Bug validating number. Please report input |%s|\n', p);
prompt_num = 1;
continue;
end
break;
end
posnum = trial_num;
end

Iniciar sesión para comentar.

Más respuestas (2)

Image Analyst
Image Analyst el 9 de Dic. de 2021
Try this:
numberOfDecimalPlaces = inf;
while numberOfDecimalPlaces >= 3
withdrawAmountString = input ('Enter amount to Withdraw : ', 's');
dotLocation = find(withdrawAmountString == '.', 1, 'last');
numberOfDecimalPlaces = length(withdrawAmountString) - dotLocation;
if numberOfDecimalPlaces >= 3
warningMessage = sprintf('You entered %d numbers to the right of the decimal point.\nPlease use 2 or less.', numberOfDecimalPlaces)
uiwait(warndlg(warningMessage));
else
% Good! It's 2 or less. Now convert string to a number.
withdrawAmount = str2double(withdrawAmountString);
end
end
  7 comentarios
Image Analyst
Image Analyst el 10 de Dic. de 2021
Sure. You can detect if there is some non-number there like this:
allDigits = all((withdrawAmountString >= '0' & withdrawAmountString <= '9') | withdrawAmountString == '.')
if ~allDigits
% Tell user they messed up.
% Then set numberOfDecimalPlaces = 3 to force it to try again.
numberOfDecimalPlaces = 3; % Ensure it will ask again.
end
Alternatively you can extract only the digits.
mask = (withdrawAmountString >= '0' & withdrawAmountString <= '9') | withdrawAmountString == '.'
withdrawAmountString(~mask) = []; % Remove non-numbers.
Tariq Hammoudeh
Tariq Hammoudeh el 11 de Dic. de 2021
Editada: Tariq Hammoudeh el 11 de Dic. de 2021
The problem with this is that it interferes with another piece of code, my code is:
transactionType= input('1:withdraw 2:deposit 3:account balance 4:end use 5:end program');
switch transactionType
%if withdraw chosen
case 1
decimalPlaces = inf; % variable for the number of decimal places in the entered withdrawal amount
%this lets the user enter a different amount if they enter an amount with more than 2 decimal places
while decimalPlaces >= 3
withdrawAmountString = input ('Enter amount to Withdraw : ', 's'); %inputed withdrawal amount
decimalLocation = find(withdrawAmountString == '.', 1, 'last');
decimalPlaces = length(withdrawAmountString) - decimalLocation;
if decimalPlaces >= 3
disp("Please limit your amount to 2 numbers to the right of the decimal point.");
else
% if enetered amount has 2 or less decimal places, convert string
% to a number and contunue.
withdrawAmount = str2double(withdrawAmountString);
end
end
noLetters = all((withdrawAmountString >= '0' & withdrawAmountString <= '9') | withdrawAmountString == '.');
if ~noLetters
withdrawAmount=input (' please enter a numeric value')
numberOfDecimalPlaces = 3;
end
%this lets the user enter a different amount if they enter a negative number
while withdrawAmount <= 0
withdrawAmount= input('invalid amount, please enter a positive number');
end
the thing with it now is that after i enter a number a number < 0 it also tells me to enter a numeric value, so how can i do it so that it only tells me this after entering a number and not when i enter a negative number
Please note: I changed it to
withdrawAmount= input(please enter numeric data) because when i would enter a letter it takes me back to switch case options instead of letting me directly enter a new number

Iniciar sesión para comentar.


David Hill
David Hill el 9 de Dic. de 2021
if you don't care about zeros entered.
x=46.4500000;%if this would be valid
if ~isequal(floor(x*100),x*100)
'invalid'
end
  1 comentario
Stephen23
Stephen23 el 10 de Dic. de 2021
Sadly this approach fails for many values that could be legitmately described as having only two decimal digits in the fraction part, for example:
x = 0:0.01:10;
y = find(floor(100*x)~=100*x)
y = 1×150
8 15 29 30 56 57 58 59 110 111 112 113 114 115 116 117 202 204 206 208 219 221 223 225 227 229 231 233 244 246
x(y)
ans = 1×150
0.0700 0.1400 0.2800 0.2900 0.5500 0.5600 0.5700 0.5800 1.0900 1.1000 1.1100 1.1200 1.1300 1.1400 1.1500 1.1600 2.0100 2.0300 2.0500 2.0700 2.1800 2.2000 2.2200 2.2400 2.2600 2.2800 2.3000 2.3200 2.4300 2.4500

Iniciar sesión para comentar.

Categorías

Más información sobre Startup and Shutdown en Help Center y File Exchange.

Etiquetas

Productos


Versión

R2020a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by