Puppy Linux Discussion Forum Forum Index Puppy Linux Discussion Forum
Puppy HOME page : puppylinux.com
"THE" alternative forum : puppylinux.info
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

The time now is Wed 20 Jun 2018, 13:57
All times are UTC - 4
 Forum index » Off-Topic Area » Programming
A simple way to detect an odd or even number in bash
Post new topic   Reply to topic View previous topic :: View next topic
Page 1 of 2 [26 Posts]   Goto page: 1, 2 Next
Author Message
musher0


Joined: 04 Jan 2009
Posts: 12319
Location: Gatineau (Qc), Canada

PostPosted: Wed 21 Feb 2018, 19:06    Post subject:  A simple way to detect an odd or even number in bash  

Hello all.

Here is a simple way to detect if a number is odd or even through a bash script.
Please pilfer and adapt to your needs! Smile

There are a couple of other ways discussed, e.g. at the stackoverflow site, but
I saw this one nowhere before.

One explained trick consists of doing a modulo by two ( " % 2 ") of your number.
if the modulo is 1, you know you have an odd number; if "0", it is an even number.

Some devs are beautiful regex acrobats and use that. (I'm in awe. Really.)

You can browse through the following pages to get a taste of the problem -- and
of some answers.
https://www.ask.com/web?qsrc=1&o=0&l=dir&q=bash+regex+detect+odd+or+even&qo=serpSearchTopBox

~~~~~~~~~~~~

I was getting nowhere with either in a script. I took a break.

After coffee, I thought: " Why not isolate the last digit of a number in a string
and compare it with the typical odd or even series?"

And the case function is the obvious to use for that. So here goes:
Code:
#!/bin/bash
# Note: it has to be bash. See the $o variable below;
# ash does not know what to do with $o-1 in the context.
#
# /opt/local/bin/OddOrEven.sh
# Or store in any "bin" directory in your $PATH.
#
# Usage: OddOrEven.sh $1
# OR
# by itself: OddOrEven.sh, and answer the prompt.
#
# Examples: OddOrEven.sh 111 # OddOrEven.sh 32
#
# # © Christian L'Écuyer, Gatineau (Qc), Canada, 2018/02/20. GPL3.
# (Alias musher0 [forum Puppy].) #
####
N=$1
if [ "$N" = "" ];then
     echo "Please type a number."
     read N
fi
o="${#N}" # ash does not know what to do with "${N:($o-1):1}" in the following.
case "${N:($o-1):1}" in
     1|3|5|7|9) echo -e "\n\t$N is an odd number.\n" ;; # If odd number.
     0|2|4|6|8) echo -e "\n\t$N is an even number.\n" ;;
esac


IHTH someone. Feedback welcome. Bye for now.
OddOrEven.sh.zip
Description 
zip

 Download 
Filename  OddOrEven.sh.zip 
Filesize  634 Bytes 
Downloaded  31 Time(s) 

_________________
musher0
~~~~~~~~~~
"Logical entities must not be multiplied beyond necessity." | |
« Il ne faut pas multiplier les entités logiques sans nécessité. » (Ockham)
Back to top
View user's profile Send private message 
MochiMoppel


Joined: 26 Jan 2011
Posts: 1536
Location: Japan

PostPosted: Wed 21 Feb 2018, 21:46    Post subject: Re: A simple way to detect an odd or even number in bash  

musher0 wrote:
Code:
${N:($o-1):1}

Same as
Code:
${N: -1}
Mind the space!
Back to top
View user's profile Send private message 
musher0


Joined: 04 Jan 2009
Posts: 12319
Location: Gatineau (Qc), Canada

PostPosted: Wed 21 Feb 2018, 22:17    Post subject:  

Hello MochiMoppei.

You are a miser, saving a variable like that! Very Happy

Bye for now.

_________________
musher0
~~~~~~~~~~
"Logical entities must not be multiplied beyond necessity." | |
« Il ne faut pas multiplier les entités logiques sans nécessité. » (Ockham)
Back to top
View user's profile Send private message 
MochiMoppel


Joined: 26 Jan 2011
Posts: 1536
Location: Japan

PostPosted: Thu 22 Feb 2018, 00:41    Post subject:  

modulo haters and ash lovers could use
Code:
o=$(echo $N | rev)
 case "${o::1}" in
Back to top
View user's profile Send private message 
musher0


Joined: 04 Jan 2009
Posts: 12319
Location: Gatineau (Qc), Canada

PostPosted: Thu 22 Feb 2018, 01:26    Post subject:  

MochiMoppel wrote:
modulo haters and ash lovers could use
Code:
o=$(echo $N | rev)
 case "${o::1}" in
Very clever, but nah... That would be spoiling the user too much! Wink
_________________
musher0
~~~~~~~~~~
"Logical entities must not be multiplied beyond necessity." | |
« Il ne faut pas multiplier les entités logiques sans nécessité. » (Ockham)
Back to top
View user's profile Send private message 
MochiMoppel


Joined: 26 Jan 2011
Posts: 1536
Location: Japan

PostPosted: Thu 22 Feb 2018, 06:17    Post subject:  

OK, that was cheating as rev does not qualify as "in bash".

This uses pure bash and works also in ash:
Code:
case $N in
  *[13579]) echo -e "\n\t$N is an odd number.\n" ;;
  *[02468]) echo -e "\n\t$N is an even number.\n" ;;
esac


[Edit]: Forgot to mention that the result can only be called "odd" or "even" if $N is an integer

Last edited by MochiMoppel on Thu 22 Feb 2018, 09:39; edited 1 time in total
Back to top
View user's profile Send private message 
puppy_apprentice


Joined: 07 Feb 2012
Posts: 184

PostPosted: Thu 22 Feb 2018, 06:28    Post subject:  

When i was learning Pascal in high school i was using this formula before i noticed that Pascal has odd function built-in.

Code:

#!/bin/sh
check=`expr $1 / 2 \* 2`
if [ $check != $1 ]
then
  echo "$1 is odd"
else
  echo "$1 is even"
fi
Back to top
View user's profile Send private message 
technosaurus


Joined: 18 May 2008
Posts: 4819
Location: Kingwood, TX

PostPosted: Thu 22 Feb 2018, 06:34    Post subject:  

For any language with bitwise operations (like bash), just use &1; however, posix shell lacks bitwise ops, so you need to use the modulus operator %
Code:
iseven() [[ $(($1%2)) = 0 ]]
isodd()  [[ $(($1%2)) = 1 ]]

_________________
Check out my github repositories. I may eventually get around to updating my blogspot.
Back to top
View user's profile Send private message Visit poster's website 
musher0


Joined: 04 Jan 2009
Posts: 12319
Location: Gatineau (Qc), Canada

PostPosted: Thu 22 Feb 2018, 11:03    Post subject:  

puppy_apprentice wrote:
When i was learning Pascal in high school i was using this formula before i noticed that Pascal has odd function built-in.
Code:

#!/bin/sh
check=`expr $1 / 2 \* 2`
if [ $check != $1 ]
then
  echo "$1 is odd"
else
  echo "$1 is even"
fi
You learned Pascal in high school? You must be very old?!?! Laughing

Euh... I thought that < expr > did not tolerate decimals. I think that if your $1 is
odd the < expr $1 \/2 > part of the calculation will exit with an error and you will
never get to the \* 2 part. I tried it in bash, and expr does not even give an error,
just a blank space, for any number.

Your trick works with bc, though, provided no "scale" if given:
Code:
n=33;echo "($n/2)*2" | bc
Quote:
32
And then your checks
Code:
if [ $check != $n ]
then
  echo "$n is odd"
else
  echo "$n is even"
fi
can be done. If a "scale" is given:
Code:
n=33;echo "scale=1;($n/2)*2" | bc
se get back the original number,
Quote:
33.0
and the test is meaningless? Maybe not: 33.0 is not identical to 33. But that ceases
to be math, IMO, it becomes the logic of identity. In a string context, string
almost-A can never be string A.

It is indeed a good idea to check the input for an integer. However it is not needed
if the input number comes from a list with, say, wc -l < list.

BFN.

_________________
musher0
~~~~~~~~~~
"Logical entities must not be multiplied beyond necessity." | |
« Il ne faut pas multiplier les entités logiques sans nécessité. » (Ockham)
Back to top
View user's profile Send private message 
musher0


Joined: 04 Jan 2009
Posts: 12319
Location: Gatineau (Qc), Canada

PostPosted: Thu 22 Feb 2018, 11:34    Post subject:  

technosaurus wrote:
For any language with bitwise operations (like bash), just use &1; however, posix shell lacks bitwise ops, so you need to use the modulus operator %
Code:
iseven() [[ $(($1%2)) = 0 ]]
isodd()  [[ $(($1%2)) = 1 ]]
Hi technosaurus.

Playing with your formula, like a kid with dough!
Code:
n=33;[ $[$n%2] = 0 ] && echo even || echo odd
Quote:
odd
BFN.
_________________
musher0
~~~~~~~~~~
"Logical entities must not be multiplied beyond necessity." | |
« Il ne faut pas multiplier les entités logiques sans nécessité. » (Ockham)
Back to top
View user's profile Send private message 
puppy_apprentice


Joined: 07 Feb 2012
Posts: 184

PostPosted: Thu 22 Feb 2018, 12:35    Post subject:  

My formula works straight only for Normal Numbers. If you have decimal like 33.0 you have to first cut .0 eg.

Code:

${1%.*}


Save as eg. evenorodd:
Code:

#!/bin/sh
number=${1%.*}
check=`expr $number / 2 \* 2`
if [ $check != $number ]
then
  echo "$1 is odd"
else
  echo "$1 is even"
fi


Some mathematics:
0) number eg. 2 is even if:
1) you divide it by 2
2) round (1)
3) multiply (2) by 2
4) (3) is equal to (0).

expr rounds number automatically so you don't need to do (2).
evenorodd.jpg
 Description   In my bash it works
 Filesize   25.6 KB
 Viewed   157 Time(s)

evenorodd.jpg

Back to top
View user's profile Send private message 
technosaurus


Joined: 18 May 2008
Posts: 4819
Location: Kingwood, TX

PostPosted: Thu 22 Feb 2018, 19:42    Post subject:  

musher0 wrote:
technosaurus wrote:
For any language with bitwise operations (like bash), just use &1; however, posix shell lacks bitwise ops, so you need to use the modulus operator %
Code:
iseven() [[ $(($1%2)) = 0 ]]
isodd()  [[ $(($1%2)) = 1 ]]
Hi technosaurus.

Playing with your formula, like a kid with dough!
Code:
n=33;[ $[$n%2] = 0 ] && echo even || echo odd
Quote:
odd
BFN.


I actually screwed up and forgot to account for negative numbers, but here is a fix... If you just paste those at the top of your script you can use them like functions

Code:
#!/bin/sh
iseven() [[ $(($1%2)) = 0 ]]
isodd() [[ ! $(($1%2)) = 0 ]]
even_odd(){
  iseven $1 && echo even || echo odd
}
even_odd 42
even_odd 7

_________________
Check out my github repositories. I may eventually get around to updating my blogspot.
Back to top
View user's profile Send private message Visit poster's website 
MochiMoppel


Joined: 26 Jan 2011
Posts: 1536
Location: Japan

PostPosted: Thu 22 Feb 2018, 21:54    Post subject:  

@musher0: Your original idea to use a case statement wasn't bad. While checking only the last digit doesn't tell you if you are dealing with an integer, you could easily adapt your case conditions to allow only integers and issue a warning if none of the conditions match. In the end such construct is not more complex than using bash arithmetic operators and doesn't require knowledge on how modulo or bash division work.

Using modulo and bash:
Code:
[[ $N = *[^0-9-]* ]] && echo $N is not an integer && exit
(($N%2)) && echo $N is odd ||  echo $N is even
Note: The integer check avoids regex, but it doesn't catch oddly placed minus signs.

For a bullet proof check this should do:
Code:
[[ $N =~ ^-?[0-9]+$ ]] || exec echo $N is not an integer


.

Last edited by MochiMoppel on Thu 22 Feb 2018, 22:43; edited 1 time in total
Back to top
View user's profile Send private message 
Flash
Official Dog Handler


Joined: 04 May 2005
Posts: 12889
Location: Arizona USA

PostPosted: Thu 22 Feb 2018, 22:12    Post subject:  

Not to hijack the thread, I'd like to throw in that a prime number cannot be an even number.
Back to top
View user's profile Send private message 
technosaurus


Joined: 18 May 2008
Posts: 4819
Location: Kingwood, TX

PostPosted: Thu 22 Feb 2018, 22:44    Post subject:  

Flash wrote:
Not to hijack the thread, I'd like to throw in that a prime number cannot be an even number.

2

_________________
Check out my github repositories. I may eventually get around to updating my blogspot.
Back to top
View user's profile Send private message Visit poster's website 
Display posts from previous:   Sort by:   
Page 1 of 2 [26 Posts]   Goto page: 1, 2 Next
Post new topic   Reply to topic View previous topic :: View next topic
 Forum index » Off-Topic Area » Programming
Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group
[ Time: 0.2441s ][ Queries: 13 (0.0121s) ][ GZIP on ]