Subtleties when using def and ifnum conditionals
Clash Royale CLAN TAG#URR8PPP
up vote
2
down vote
favorite
I am having some difficultly comparing two numbers passed as arguments using ifnum
. Consider the command
defcomparenum[#1,#2]
defx#1
defy#2
ifnumx=y
TRUE
else
FALSE
fi
comparenum[1,1]
gives TRUE
as I would expect. However, if I replace the above with
ifnumx=y
1
else
0
fi
The same call comparenum[1,1]
produces 0
(replacing y
with y
, or indeed #2
seems to fix this). What is the reason for this behaviour? I would like to use the second construction so that I can nest the statement inside another conditional as in the top answer to How to form “if … or … then†conditionals in TeX?
tex-core conditionals
New contributor
Pippip19 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
 |Â
show 3 more comments
up vote
2
down vote
favorite
I am having some difficultly comparing two numbers passed as arguments using ifnum
. Consider the command
defcomparenum[#1,#2]
defx#1
defy#2
ifnumx=y
TRUE
else
FALSE
fi
comparenum[1,1]
gives TRUE
as I would expect. However, if I replace the above with
ifnumx=y
1
else
0
fi
The same call comparenum[1,1]
produces 0
(replacing y
with y
, or indeed #2
seems to fix this). What is the reason for this behaviour? I would like to use the second construction so that I can nest the statement inside another conditional as in the top answer to How to form “if … or … then†conditionals in TeX?
tex-core conditionals
New contributor
Pippip19 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
1
You may want to look intoetoolbox
and itsifnumequal
test. Together withifboolexpr
you can easily nest stuff. But you can also look intoexpl3
and its vast array of tests.
– moewe
53 mins ago
Your first code produces TRUE but does not produce FALSE if you callcomparenum[1,2]
.
– Sigur
52 mins ago
@Sigur I just realised the same.defx#1 defy#1
could explain that ;-) But I'm wondering why thedef
's are needed at all...ifnum#1=#2
should do more or less the same.
– moewe
51 mins ago
If you want to be able to use1
and0
as "return" values you should tryifnumx=yrelax
– moewe
50 mins ago
@moewe, ohhhhh, I missed that!!! Good!
– Sigur
50 mins ago
 |Â
show 3 more comments
up vote
2
down vote
favorite
up vote
2
down vote
favorite
I am having some difficultly comparing two numbers passed as arguments using ifnum
. Consider the command
defcomparenum[#1,#2]
defx#1
defy#2
ifnumx=y
TRUE
else
FALSE
fi
comparenum[1,1]
gives TRUE
as I would expect. However, if I replace the above with
ifnumx=y
1
else
0
fi
The same call comparenum[1,1]
produces 0
(replacing y
with y
, or indeed #2
seems to fix this). What is the reason for this behaviour? I would like to use the second construction so that I can nest the statement inside another conditional as in the top answer to How to form “if … or … then†conditionals in TeX?
tex-core conditionals
New contributor
Pippip19 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
I am having some difficultly comparing two numbers passed as arguments using ifnum
. Consider the command
defcomparenum[#1,#2]
defx#1
defy#2
ifnumx=y
TRUE
else
FALSE
fi
comparenum[1,1]
gives TRUE
as I would expect. However, if I replace the above with
ifnumx=y
1
else
0
fi
The same call comparenum[1,1]
produces 0
(replacing y
with y
, or indeed #2
seems to fix this). What is the reason for this behaviour? I would like to use the second construction so that I can nest the statement inside another conditional as in the top answer to How to form “if … or … then†conditionals in TeX?
tex-core conditionals
tex-core conditionals
New contributor
Pippip19 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
Pippip19 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
edited 16 mins ago
New contributor
Pippip19 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
asked 1 hour ago
Pippip19
132
132
New contributor
Pippip19 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
Pippip19 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
Pippip19 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
1
You may want to look intoetoolbox
and itsifnumequal
test. Together withifboolexpr
you can easily nest stuff. But you can also look intoexpl3
and its vast array of tests.
– moewe
53 mins ago
Your first code produces TRUE but does not produce FALSE if you callcomparenum[1,2]
.
– Sigur
52 mins ago
@Sigur I just realised the same.defx#1 defy#1
could explain that ;-) But I'm wondering why thedef
's are needed at all...ifnum#1=#2
should do more or less the same.
– moewe
51 mins ago
If you want to be able to use1
and0
as "return" values you should tryifnumx=yrelax
– moewe
50 mins ago
@moewe, ohhhhh, I missed that!!! Good!
– Sigur
50 mins ago
 |Â
show 3 more comments
1
You may want to look intoetoolbox
and itsifnumequal
test. Together withifboolexpr
you can easily nest stuff. But you can also look intoexpl3
and its vast array of tests.
– moewe
53 mins ago
Your first code produces TRUE but does not produce FALSE if you callcomparenum[1,2]
.
– Sigur
52 mins ago
@Sigur I just realised the same.defx#1 defy#1
could explain that ;-) But I'm wondering why thedef
's are needed at all...ifnum#1=#2
should do more or less the same.
– moewe
51 mins ago
If you want to be able to use1
and0
as "return" values you should tryifnumx=yrelax
– moewe
50 mins ago
@moewe, ohhhhh, I missed that!!! Good!
– Sigur
50 mins ago
1
1
You may want to look into
etoolbox
and its ifnumequal
test. Together with ifboolexpr
you can easily nest stuff. But you can also look into expl3
and its vast array of tests.– moewe
53 mins ago
You may want to look into
etoolbox
and its ifnumequal
test. Together with ifboolexpr
you can easily nest stuff. But you can also look into expl3
and its vast array of tests.– moewe
53 mins ago
Your first code produces TRUE but does not produce FALSE if you call
comparenum[1,2]
.– Sigur
52 mins ago
Your first code produces TRUE but does not produce FALSE if you call
comparenum[1,2]
.– Sigur
52 mins ago
@Sigur I just realised the same.
defx#1 defy#1
could explain that ;-) But I'm wondering why the def
's are needed at all... ifnum#1=#2
should do more or less the same.– moewe
51 mins ago
@Sigur I just realised the same.
defx#1 defy#1
could explain that ;-) But I'm wondering why the def
's are needed at all... ifnum#1=#2
should do more or less the same.– moewe
51 mins ago
If you want to be able to use
1
and 0
as "return" values you should try ifnumx=yrelax
– moewe
50 mins ago
If you want to be able to use
1
and 0
as "return" values you should try ifnumx=yrelax
– moewe
50 mins ago
@moewe, ohhhhh, I missed that!!! Good!
– Sigur
50 mins ago
@moewe, ohhhhh, I missed that!!! Good!
– Sigur
50 mins ago
 |Â
show 3 more comments
1 Answer
1
active
oldest
votes
up vote
2
down vote
accepted
Your second code is equivalent to
defcomparenum[#1,#2] defx#1 defy#1 ifnumx=y1 else0 fi
(because spaces and end-of-lines are ignored after a control word). Now you should be able to see the main problem with the code. When TeX evaluates the conditional, it needs two numbers and does full expansion until finding tokens that cannot be interpreted as digits.
So it expands x
and =
stops the search for digits while also starting the lookup for the next number; y
is expanded and 1
follows. So the call comparenum[1,1]
translates into
ifnum1=11 else0 fi
which of course returns false.
You solve the issue with
defcomparenum[#1,#2]%
defx#1%
defy#1%
ifnumx=yrelax
1%
else
0%
fi
The relax
token stops the lookup for digits.
On the other hand, this construct is not expandable. You can make an expandable version with
defcomparenum[#1,#2]%
ifnum#1=number#2spacespace
1%
else
0%
fi
The first space
expands to a space token that stops number
from looking up for more digits and is then ignored by rule; the second space
stops the search for digit related to ifnum
and is again ignored.
An e-TeX version would be
defcomparenum[#1,#2]%
ifnum#1=numexpr#2relax
1%
else
0%
fi
Please, note the %
that protect the end-of-lines avoiding that they make spaces in the output.
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
Your second code is equivalent to
defcomparenum[#1,#2] defx#1 defy#1 ifnumx=y1 else0 fi
(because spaces and end-of-lines are ignored after a control word). Now you should be able to see the main problem with the code. When TeX evaluates the conditional, it needs two numbers and does full expansion until finding tokens that cannot be interpreted as digits.
So it expands x
and =
stops the search for digits while also starting the lookup for the next number; y
is expanded and 1
follows. So the call comparenum[1,1]
translates into
ifnum1=11 else0 fi
which of course returns false.
You solve the issue with
defcomparenum[#1,#2]%
defx#1%
defy#1%
ifnumx=yrelax
1%
else
0%
fi
The relax
token stops the lookup for digits.
On the other hand, this construct is not expandable. You can make an expandable version with
defcomparenum[#1,#2]%
ifnum#1=number#2spacespace
1%
else
0%
fi
The first space
expands to a space token that stops number
from looking up for more digits and is then ignored by rule; the second space
stops the search for digit related to ifnum
and is again ignored.
An e-TeX version would be
defcomparenum[#1,#2]%
ifnum#1=numexpr#2relax
1%
else
0%
fi
Please, note the %
that protect the end-of-lines avoiding that they make spaces in the output.
add a comment |Â
up vote
2
down vote
accepted
Your second code is equivalent to
defcomparenum[#1,#2] defx#1 defy#1 ifnumx=y1 else0 fi
(because spaces and end-of-lines are ignored after a control word). Now you should be able to see the main problem with the code. When TeX evaluates the conditional, it needs two numbers and does full expansion until finding tokens that cannot be interpreted as digits.
So it expands x
and =
stops the search for digits while also starting the lookup for the next number; y
is expanded and 1
follows. So the call comparenum[1,1]
translates into
ifnum1=11 else0 fi
which of course returns false.
You solve the issue with
defcomparenum[#1,#2]%
defx#1%
defy#1%
ifnumx=yrelax
1%
else
0%
fi
The relax
token stops the lookup for digits.
On the other hand, this construct is not expandable. You can make an expandable version with
defcomparenum[#1,#2]%
ifnum#1=number#2spacespace
1%
else
0%
fi
The first space
expands to a space token that stops number
from looking up for more digits and is then ignored by rule; the second space
stops the search for digit related to ifnum
and is again ignored.
An e-TeX version would be
defcomparenum[#1,#2]%
ifnum#1=numexpr#2relax
1%
else
0%
fi
Please, note the %
that protect the end-of-lines avoiding that they make spaces in the output.
add a comment |Â
up vote
2
down vote
accepted
up vote
2
down vote
accepted
Your second code is equivalent to
defcomparenum[#1,#2] defx#1 defy#1 ifnumx=y1 else0 fi
(because spaces and end-of-lines are ignored after a control word). Now you should be able to see the main problem with the code. When TeX evaluates the conditional, it needs two numbers and does full expansion until finding tokens that cannot be interpreted as digits.
So it expands x
and =
stops the search for digits while also starting the lookup for the next number; y
is expanded and 1
follows. So the call comparenum[1,1]
translates into
ifnum1=11 else0 fi
which of course returns false.
You solve the issue with
defcomparenum[#1,#2]%
defx#1%
defy#1%
ifnumx=yrelax
1%
else
0%
fi
The relax
token stops the lookup for digits.
On the other hand, this construct is not expandable. You can make an expandable version with
defcomparenum[#1,#2]%
ifnum#1=number#2spacespace
1%
else
0%
fi
The first space
expands to a space token that stops number
from looking up for more digits and is then ignored by rule; the second space
stops the search for digit related to ifnum
and is again ignored.
An e-TeX version would be
defcomparenum[#1,#2]%
ifnum#1=numexpr#2relax
1%
else
0%
fi
Please, note the %
that protect the end-of-lines avoiding that they make spaces in the output.
Your second code is equivalent to
defcomparenum[#1,#2] defx#1 defy#1 ifnumx=y1 else0 fi
(because spaces and end-of-lines are ignored after a control word). Now you should be able to see the main problem with the code. When TeX evaluates the conditional, it needs two numbers and does full expansion until finding tokens that cannot be interpreted as digits.
So it expands x
and =
stops the search for digits while also starting the lookup for the next number; y
is expanded and 1
follows. So the call comparenum[1,1]
translates into
ifnum1=11 else0 fi
which of course returns false.
You solve the issue with
defcomparenum[#1,#2]%
defx#1%
defy#1%
ifnumx=yrelax
1%
else
0%
fi
The relax
token stops the lookup for digits.
On the other hand, this construct is not expandable. You can make an expandable version with
defcomparenum[#1,#2]%
ifnum#1=number#2spacespace
1%
else
0%
fi
The first space
expands to a space token that stops number
from looking up for more digits and is then ignored by rule; the second space
stops the search for digit related to ifnum
and is again ignored.
An e-TeX version would be
defcomparenum[#1,#2]%
ifnum#1=numexpr#2relax
1%
else
0%
fi
Please, note the %
that protect the end-of-lines avoiding that they make spaces in the output.
answered 19 mins ago


egreg
691k8518383086
691k8518383086
add a comment |Â
add a comment |Â
Pippip19 is a new contributor. Be nice, and check out our Code of Conduct.
Pippip19 is a new contributor. Be nice, and check out our Code of Conduct.
Pippip19 is a new contributor. Be nice, and check out our Code of Conduct.
Pippip19 is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f456106%2fsubtleties-when-using-def-and-ifnum-conditionals%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
1
You may want to look into
etoolbox
and itsifnumequal
test. Together withifboolexpr
you can easily nest stuff. But you can also look intoexpl3
and its vast array of tests.– moewe
53 mins ago
Your first code produces TRUE but does not produce FALSE if you call
comparenum[1,2]
.– Sigur
52 mins ago
@Sigur I just realised the same.
defx#1 defy#1
could explain that ;-) But I'm wondering why thedef
's are needed at all...ifnum#1=#2
should do more or less the same.– moewe
51 mins ago
If you want to be able to use
1
and0
as "return" values you should tryifnumx=yrelax
– moewe
50 mins ago
@moewe, ohhhhh, I missed that!!! Good!
– Sigur
50 mins ago