**You are now following this question**

- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.

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

4 views (last 30 days)

Show older comments

Tariq Hammoudeh
on 9 Dec 2021

Edited: Walter Roberson
on 13 Dec 2021

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')

##### 0 Comments

### Accepted Answer

Walter Roberson
on 10 Dec 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

S = sprintf('%.99g', withdrawAmount)

length(S)

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 Comments

Tariq Hammoudeh
on 10 Dec 2021

Walter Roberson
on 10 Dec 2021

withdrawAmountString = input ('Enter amount to Withdraw : ', 's'); %inputed withdrawal amount

vetted = regexp(withdrawAmountString, '^([0-9]+(\.[0-9]{0,2})?$)|^\.[0-9]{1,2}$', 'match');

if isempty(vetted)

user did not enter valid string

else

withdrawAmount = str2double(vetted);

end

You might prefer to use the newer pattern facility if your MATLAB is new enough.

Tariq Hammoudeh
on 10 Dec 2021

Walter Roberson
on 11 Dec 2021

while true

withdrawAmountString = input ('Enter amount to Withdraw : ', 's'); %inputed withdrawal amount

vetted = regexp(withdrawAmountString, '^([0-9]+(\.[0-9]{0,2})?$)|^\.[0-9]{1,2}$', 'match');

if ~isempty(vetted)

withdrawAmount = str2double(vetted);

break

end

end

Tariq Hammoudeh
on 11 Dec 2021

thank you for that but now when i add it to the rest of my code:

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

while true

withdrawAmountString = input ('please enter a numeric value : ', 's'); %inputed withdrawal amount

vetted = regexp(withdrawAmountString, '^([0-9]+(\.[0-9]{0,2})?$)|^\.[0-9]{1,2}$', 'match');

if ~isempty(vetted)

withdrawAmount = str2double(vetted);

break

end

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

%this lets the user enter a different amount, if they enter an amount that is more than the ATM's cash reserve

while withdrawAmount > CR

withdrawAmount = input('insufficient funds in ATM, please enter a different amount');

end

What happens is that, if i start by entering a number < 0 it aslo tells me to "enter a numeric value" instead of "enter a positive value", and also if i start with a number greater than CR i also get "enter a numeric value", and the only way for me to get the correct message for a number greater than CR is only after i either enter a negative number or a letter and the try after that will give me the correct message. so how can i make it give me the correct message for each

Walter Roberson
on 11 Dec 2021

What happens is that, if i start by entering a number < 0 it aslo tells me to "enter a numeric value" instead of "enter a positive value",

You never indicated that negative should be considered. Why bother to consider it separately when you could simply declare that negative is an invalid value and change the first message to 'please enter a positive numeric value' ?

But if you must...

vetted = regexp(withdrawAmountString, '^(-?[0-9]+(\.[0-9]{0,2})?$)|^\-?.[0-9]{1,2}$', 'match');

Note that this requires that the - is directly beside the number. If you want to permit spaces then the code would have to be changed a little. Also, if you want to permit leading or trailing spaces then the code would have to be changed a little.

Walter Roberson
on 11 Dec 2021

while withdrawAmount > CR

withdrawAmount = input('insufficient funds in ATM, please enter a different amount');

end

That code does not validate the input amount.

You should create a function that loops until it gets a validated positive number. Using a function would make your code a lot cleaner.

Tariq Hammoudeh
on 11 Dec 2021

vetted = regexp(withdrawAmountString, '^(-?[0-9]+(\.[0-9]{0,2})?$)|^\-?.[0-9]{1,2}$', 'match');

i tried this but now what happens is that if i enter a negative number i get the correct message, also if i enter a letter i also get the correct message, but then if i enter a letter and get the message "please enter a positive numeric value" then i enter a negative number, here the code continues and takes the negative number as the withdraw amount. So how can i fix that.

Also for your second point:

while withdrawAmount > CR

withdrawAmount = input('insufficient funds in ATM, please enter a different amount');

end

This code works fine and it doesnt let me enter a value more than CR and lets me try again,

Tariq Hammoudeh
on 11 Dec 2021

Walter Roberson
on 11 Dec 2021

while true

withdrawAmount = getPositiveNumber();

if withdrawAmount > CR

fprintf('insufficient funds in ATM, please enter a different amount\n');

else

break

end

end

function posnum = getPositiveNumber()

prompt1 = 'please enter a numeric value : ';

prompt2 = 'please enter a positive value : ';

prev_was_negative = false;

while true

if prev_was_negative

prompt = prompt2;

else

prompt = prompt1;

end

p = input(prompt, 's');

vetted = regexp(p, '^(-?[0-9]+(\.[0-9]{0,2})?$)|^-?\.[0-9]{1,2}$', 'match');

if isempty(vetted)

prev_was_negative = false;

% fail to match pattern, do nothing special, loop will repeat

else

trial_num = str2double(vetted);

if trial_num < 0

prev_was_negative = true;

elseif ~isnan(trial_num)

prev_was_negative = false;

break

else

% somehow vetted number converted to nan ??

fprintf('Bug validating number. Please report input |%s|\n', p)

end

end

end

posnum = trial_num;

end

Walter Roberson
on 11 Dec 2021

Tariq Hammoudeh
on 11 Dec 2021

Tariq Hammoudeh
on 11 Dec 2021

I tried the new one but it still tells me " enter a numeric value" even if i enter a valid amount.

This is from the command window:

Enter account number 105

1:withdraw 2:deposit 3:account balance 4:end use 5:end program 1

Enter amount to Withdraw : 10

please enter a numeric value :

also if i enter a negative number the first time it displays "enter a numeric value", it only displays "enter a positive number" after the second time of entering a negative number:

Enter account number 234

1:withdraw 2:deposit 3:account balance 4:end use 5:end program 1

Enter amount to Withdraw : -10

please enter a numeric value : -10

please enter a positive value :

Tariq Hammoudeh
on 11 Dec 2021

This is all the code related to withdrawing only:

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

while true

withdrawAmount = getPositiveNumber();

if withdrawAmount > CR

fprintf('insufficient funds in ATM, please enter a different amount\n');

else

break

end

end

%this lets the user know that they have dont have enough money in their account and lets them enter a different amount

while (withdrawAmount + 1.5) > Data.Balance(ac)

fprintf( 'INSUFICCIENT FUNDS Your current balance is : %.2f \n', Data.Balance(ac))

withdrawAmount = input('Please enter a different amount ');

end

%if there are suffiecient funds

if withdrawAmount + 1.5 <= Data.Balance(ac)

denominationCount(withdrawAmount); %call function to count the least number of coins and notes.

%subtract the withdrawn amount and the service charge from the

%user's account balance

Data.Balance(ac)= Data.Balance(ac)-(withdrawAmount + 1.5);

writetable(Data, 'NaiveBankData.csv'); %update the csv file with the new balance

%removing the withdrawn amount from the cash reserve

CR=CR- withdrawAmount;

%write the new cash reserve number into the cash reserve file

writematrix(CR, reserve);

fprintf('An amount of: %.2f \n has been debited from your account. ', (withdrawAmount + 1.5))

fprintf(' Your remaining balance is: %.2f \n ', Data.Balance(ac))

function posnum = getPositiveNumber()

prompt1 = 'please enter a numeric value : ';

prompt2 = 'please enter a positive value : ';

prev_was_negative = false;

while true

if prev_was_negative

prompt = prompt2;

else

prompt = prompt1;

end

p = input(prompt, 's');

vetted = regexp(p, '^(-?[0-9]+(\.[0-9]{0,2})?$)|^-?\.[0-9]{1,2}$', 'match');

if isempty(vetted)

prev_was_negative = false;

% fail to match pattern, do nothing special, loop will repeat

else

trial_num = str2double(vetted);

if trial_num < 0

prev_was_negative = true;

elseif ~isnan(trial_num)

prev_was_negative = false;

break

else

% somehow vetted number converted to nan ??

fprintf('Bug validating number. Please report input |%s|\n', p)

end

end

end

posnum = trial_num;

end

Image Analyst
on 12 Dec 2021

Walter Roberson
on 12 Dec 2021

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

Get rid of that entire section. That section of code should start directly with

while true

withdrawAmount = getPositiveNumber();

If you want to specifically tell the user off about having too many decimal places, then edit the getPositiveNumber() function. In particular, you would give that error if

~isempty(regexp(p, '\.[0-9]{3,}'))

which matches a literal period followed by at least 3 digits.

Tariq Hammoudeh
on 12 Dec 2021

Ok i edited it to the following and it does work, it doesnt let me put more than 2 decimal places, but how can i make the 3rd prompt appear when if ~isempty(regexp(p, '\.[0-9]{3,}'))

function posnum = getPositiveNumber()

prompt1 = 'please enter a numeric amount : ';

prompt2 = 'please enter a positive value : ';

prompt3= 'please limit your amount to 2 decimal places : ';

prev_was_negative = false;

while true

if prev_was_negative

prompt = prompt2;

else

prompt = prompt1;

end

p = input(prompt, 's');

vetted = regexp(p, '^(-?[0-9]+(\.[0-9]{0,2})?$)|^-?\.[0-9]{1,2}$', 'match');

if isempty(vetted)

prev_was_negative = false;

% fail to match pattern, do nothing special, loop will repeat

else

trial_num = str2double(vetted);

if trial_num < 0

prev_was_negative = true;

elseif ~isnan(trial_num)

prev_was_negative = false;

break

else

% somehow vetted number converted to nan ??

fprintf('Bug validating number. Please report input |%s|\n', p)

end

if ~isempty(regexp(p, '\.[0-9]{3,}'))

prev_was_negative = false;

end

end

end

posnum = trial_num;

end

If you cant answer me its fine, but this is my last issue for my entire program and its done

Tariq Hammoudeh
on 13 Dec 2021

I tried

if ~isempty(regexp(p, '\.[0-9]{3,}'))

disp('use 2 decimal places only')

end

and

if ~isempty(regexp(p, '\.[0-9]{3,}'))

withdrawAmount= input('use 2 decimal places only')

end

and neither worked

Walter Roberson
on 13 Dec 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

% fail to match pattern, do nothing special, loop will repeat

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

Tariq Hammoudeh
on 13 Dec 2021

but when that is combined with that:

while true

withdrawAmount = getPositiveNumber(); %call function that loops an invalid withdrawal amount

if withdrawAmount > CR

fprintf('insufficient funds in ATM, please enter a different amount\n');

else

break %if amount is valid, break out of loop and continue

end

end

the withdraw amount doesnt get processed it just keeps asking for a withdraw amount

Walter Roberson
on 13 Dec 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

### More Answers (2)

Image Analyst
on 9 Dec 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 Comments

Tariq Hammoudeh
on 10 Dec 2021

i tried this but i dont need the warning message, so i changed it to:

decimalPlaces = inf;

while decimalPlaces >= 3

withdrawAmountString = input ('Please limit your entered amount to 2 numbers to the right of the decimal point : ', 's');

dotLocation = find(withdrawAmountString == '.', 1, 'last');

decimalPlaces = length(withdrawAmountString) - dotLocation;

if decimalPlaces >= 3

disp('please limit amount to 2 decimal places')

else

% Good! It's 2 or less. Now convert string to a number.

withdrawAmount = str2double(withdrawAmountString);

end

end

But the first time i enter a number with 3 decimal places it just displays the message "Please limit your entered amount to 2 numbers to the right of the decimal point" and lets me enter another amount, but the second time i enter a number with 3 decimal places it displays both messages and lets me enter an amount again. So how can i make it so that only the "Please limit your entered amount to 2 numbers to the right of the decimal point" displays each time.

Tariq Hammoudeh
on 10 Dec 2021

Image Analyst
on 10 Dec 2021

Right. That's working as intended. Each time you enter 3 or more decimal places, it will notify that you did it wrong and will give you another opportunity to enter a number with 0, 1, or 2 decimal places. Isn't that what you said you wanted?

If you don't like my popup warning message, and simply want to display the confusing "invalid" with no explanation why the input is invalid, then you can confuse the user by doing 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

disp("Invalid.");

else

% Good! It's 2 or less. Now convert string to a number.

withdrawAmount = str2double(withdrawAmountString);

end

end

Frankly I think my error message is more informative than just saying "invalid" like you suggested.

Tariq Hammoudeh
on 10 Dec 2021

apologies the previous code did work i mixed something up, so thank you

Also i just wrote invalid to ask the question, thats not the message i have in my code.

Tariq Hammoudeh
on 10 Dec 2021

Image Analyst
on 10 Dec 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
on 11 Dec 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

David Hill
on 9 Dec 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 Comment

Stephen23
on 10 Dec 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

### See Also

### Community Treasure Hunt

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

Start Hunting!**An Error Occurred**

Unable to complete the action because of changes made to the page. Reload the page to see its updated state.