Find out if number is divisible by x

198 views (last 30 days)
RP
RP on 8 Apr 2019
Answered: Uriel Serrato on 23 Jul 2020
I'm trying to write a function that determines if the input is a valid date, and for that I need a function that will tell me if an input number is divisible by 4 and at the same time not divisible by 100 (this has to do with leap years but I'm not supposed to use the special function for that). This is what I came up with but I can already see that it's not correct. In non-code language, I would like it to be something like "If divisors(year) contains the number 4 and does not contain the number 100, display the following..." but I did not know how to do this.
(This is just the part of code I'm struggling with, I didn't paste everything because it was quite a lot.)
Any tips on how I should fix it would be much appreciated!
function valid = valid_date(year,month,day)
if divisors(year) = 4 ~ 100
.
.
.
.
.
end

Accepted Answer

RP
RP on 9 Apr 2019
Edited: RP on 9 Apr 2019
Thank you for your help so far! So now I came up with this and it works with some dates but not with most; For example, I tried it with the input (2001,1,32) and it returns "1" although the input is not a correct date.
Also sometimes I'm getting the error message Output argument "valid" (and maybe others) not assigned during call to "valid_date".
I don't know what that message means and what else is wrong in my code, maybe someone can point out where the mistake is?
function valid = valid_date(year,month,day)
% leap year: divisible by 4, not by 100 -> February has 29 days
if mod(year,4) == 0 & mod(year,100) == ~0;
if month == 2;
if 1 <= day <= 29;
valid = true;
else
valid = false;
end
elseif month == 1 | 3 | 5 | 7 | 8 | 10 | 12;
if 1 <= day <= 31;
valid = true;
else
valid = false;
end
elseif month == 4 | 6 | 9 | 11;
if 1 <= day <= 30;
valid = true;
else
valid = false;
end
else
valid = false;
end
% leap year: divisible by 400 -> February has 29 days
elseif mod(year,400) == 0;
if month == 2;
if 1 <= day <= 29;
valid = true;
else
valid = false;
end
elseif month == 1 | 3 | 5 | 7 | 8 | 10 | 12;
if 1 <= day <= 31;
valid = true;
else
valid = false;
end
elseif month == 2 | 4 | 6 | 9 | 11;
if 1 <= day <= 30;
valid = true;
else
valid = false;
end
else
valid = false;
end
% normal year -> February has 28 days
else
if month == 2;
if 1 <= day <= 28;
valid = true;
else
valid = false;
end
elseif month == 1 | 3 | 5 | 7 | 8 | 10 | 12;
if 1 <= day <= 31;
valid = true;
else
valid = false;
end
elseif month == 4 | 6 | 9 | 11;
if 1 <= day <= 30;
valid = true;
else
valid = false;
end
else
valid = false;
end
end
end
  2 Comments
Steven Lord
Steven Lord on 9 Apr 2019
There are a couple problems with your code.
if mod(year,4) == 0 & mod(year,100) == ~0;
mod(year, 100) == ~0 is true only when year is 1 greater than a multiple of 100, because the logical negation of 0 is true which is treated as equal to 1 in most circumstances. To test if two numbers are not equal, use the ~= operator.
5 ~= 5 % false
5 ~= 4 % true
The second problem is here:
if month == 2;
if 1 <= day <= 29;
If you've written this in the MATLAB Editor and you're using a release from the past year or two, you should have received a Code Analyzer warning message (a little orange line in the right gutter and an orange underline of some portion of this expression.) That if condition is always true, because it is interpreted as (1 <= day) <= 29. (1 <= day) will be either false (treated as 0) or true (treated as 1) both of which are less than or equal to 29. Code Analyzer will recommend the following:
(1 <= day) & (day <= 29)
Finally:
valid = true;
else
valid = false;
end
elseif month == 1 | 3 | 5 | 7 | 8 | 10 | 12;
If reached this elseif statement is always satisfied. This is not interpreted as "if month is one of 1, 3, 5, 7, 8, 10, or 12". It is interpreted as "if month is equal to 1 or 3 is nonzero or 5 is nonzero or ..." Since or (the | operator) requires at least one of its inputs to be true to return true and 3 is nonzero, the whole expression is true.
To determine if month is one of a set of numbers, you can either use switch or ismember.
ismember(4, [4 8 15 16 23 42]) % true
ismember(99, [4 8 15 16 23 42]) % false
x = 4; % Try redefining x to be 12 or 99 and rerun the switch
switch x
case {4 8 15 16 23 42}
disp('Yes!')
case {12 87}
disp('Brady and Gronk!')
otherwise
disp('No!')
end
Or you could hard-code a list of last days of the month and simply index into it, then treat February (which may have a different number of days) specially.
RP
RP on 9 Apr 2019
Thank you SO much for your time, this is very helpful and now the code is running without problems!

Sign in to comment.

More Answers (2)

Steven Lord
Steven Lord on 8 Apr 2019
Take a look at the rem and mod functions.
  5 Comments
RP
RP on 8 Apr 2019
Ahh I see! This should work then, right?
if mod(x,y) = 0
...
else
...
end
James Tursa
James Tursa on 8 Apr 2019
The = is an assignment operator in MATLAB. The == is the equality test operator. So
if mod(x,y) == 0

Sign in to comment.


Uriel Serrato
Uriel Serrato on 23 Jul 2020
function valid=valid_date(year,month,day)
if isscalar(year)==false || isscalar(month)==false || isscalar(day)==false
valid=false ;
return
end
if ((1<= month) && (month<= 12)) && ((1<= day) && (day<= 31)) && (month==1||month==3||month==5||month==7||month==8||month==10||month==12)
valid=true;
elseif ((1<= month) && (month<= 12)) && ((1<= day) && (day<= 30)) && ((month==4||month==6||month==9||month==11))
valid=true;
elseif ((1<= month) && (month<= 12)) && ((1<= day) && (day<= 29)) && (month==2)&& (mod(year,4)==0 || mod(year,400)==0) && ~mod(year,100)==0
valid= true;
elseif ((1<= month) && (month<= 12)) && ((1<= day) && (day<= 28)) && (month==2)
valid=true;
else
valid=false;
end

Tags

Community Treasure Hunt

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

Start Hunting!