A simple way to detect an odd or even number in bash

For discussions about programming, programming questions/advice, and projects that don't really have anything to do with Puppy.
Message
Author
User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#21 Post by technosaurus »

MochiMoppel wrote:
technosaurus wrote:for a non bashism version (as long as parameters don't contain spaces)

Code: Select all

isnumber() [[ $(($1+0)) = ${1} ]]
AFAIK double brackets are not POSIX compliant though bash supports them also in its "more closely to the POSIX standard" mode.
crap, you are right, always get that backwards - it should still work if you change them to single brackets as long as the parameters are quoted or don't contain spaces, newlines or tabs. FWIW both busybox shells (ash and hush) support both forms.
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
MochiMoppel
Posts: 2084
Joined: Wed 26 Jan 2011, 09:06
Location: Japan

#22 Post by MochiMoppel »

technosaurus wrote:it should still work if you change them to single brackets as long as the parameters are quoted or don't contain spaces, newlines or tabs
No, it does not work
- A single bracket is an ordinary command. The function requires curly braces.
- $(($1+0)) will generate an irrecoverable syntax error if the parameter contains a decimal separator, which makes this test unsuitable as an integer check. Same happens with double brackets.

The following code should work better. Spaces etc. in parameters will lead to a correct "not an integer" result
Decimal separators will not generate a fatal syntax error.

Code: Select all

isnumber() { test "$@" -eq "$@"  2>/dev/null ;}

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#23 Post by technosaurus »

MochiMoppel wrote:The function requires curly braces.
It can be any compound statement which also includes a subshell "( ... )" in Posix and "[[ ... ]]" in bash, ksh (since 1988) and any modern shell including busybox and just about everything but dash. I didn't realize that even with "{ ... }", the compound statement can also be followed by redirection of stdin, stdout, stderr (useful for logging). The double bracket version does have some subtle differences though. I seem to have gotten a bit rusty on my shell programming. Likely because I have been using C primarily for the last few years and mostly awk right before that. Perhaps I should write myself a manual as I relearn it for the next time I forget. Tentatively titled "The Portable Shell Scripting Guide" as an answer to "The Advanced Bash Scripting Guide" ... DashAsBinSh mainly describes pitfalls without offering solutions
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
NeroVance
Posts: 201
Joined: Wed 10 Oct 2012, 23:00
Location: Halifax, Canada

#24 Post by NeroVance »

musher0 wrote:
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: Select all

#!/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?!?! :lol:
Oddly enough I'm only 24, but my older sister learned Pascal in High School from what I recall.

musher0
Posts: 14629
Joined: Mon 05 Jan 2009, 00:54
Location: Gatineau (Qc), Canada

#25 Post by musher0 »

That's funny. Being 24 is not odd! :D Being 24 is being young!

I was saying that because Pascal is an old computer language,
as computer languages go.
musher0
~~~~~~~~~~
"You want it darker? We kill the flame." (L. Cohen)

jafadmin
Posts: 1249
Joined: Thu 19 Mar 2009, 15:10

#26 Post by jafadmin »

Check the least significant bit: ((($MyVal&1)==0))

Code: Select all

  MyVal=221;((($MyVal&1)==0)) && echo "$MyVal is even" || echo "$MyVal is odd"
Or ...

Code: Select all

if (($MyVal&1))
then 	echo "$MyVal is odd"
else 	echo "$MyVal is even"
fi
In C:

Code: Select all

int MyVal = 332;
printf( "Value of MyVal is %s\n", (MyVal&1) ? "odd": "even" );

Post Reply