필터 지우기
필터 지우기

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

조회 수: 5 (최근 30일)
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')

채택된 답변

Walter Roberson
Walter Roberson 2021년 12월 10일
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
Walter Roberson
Walter Roberson 2021년 12월 13일
편집: Walter Roberson 2021년 12월 13일
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

댓글을 달려면 로그인하십시오.

추가 답변 (2개)

Image Analyst
Image Analyst 2021년 12월 9일
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
Image Analyst
Image Analyst 2021년 12월 10일
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 2021년 12월 11일
편집: Tariq Hammoudeh 2021년 12월 11일
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

댓글을 달려면 로그인하십시오.


David Hill
David Hill 2021년 12월 9일
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
Stephen23
Stephen23 2021년 12월 10일
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

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Logical에 대해 자세히 알아보기

태그

제품


릴리스

R2020a

Community Treasure Hunt

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

Start Hunting!

Translated by