LinuxQuestions.org
Support LQ: Use code LQ3 and save $3 on Domain Registration
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Thread Tools
Old 06-24-2005, 11:24 AM   #1
abefroman
Member
 
Registered: Feb 2004
Location: Chicago
Distribution: CentOS w/Cpanel
Posts: 908
Thanked: 3
How can I compare floating number in a shell script?


[Log in to get rid of this advertisement]
root@server1 [/]# ./ss3
./ss3: [: 3.1: integer expression expected
root@server1 [/]# cat ss3
#!/bin/bash
X=3.1
Y=3.2
empty_string=""
if [ $X -lt $Y ] # is $X less than $Y ?
then
echo "\$X=${X}, which is greater than \$Y=${Y}"
fi

Why does it say integer expression expected? How can I compare floats?

===========================================
It wont even work in C shell
root@server1 [/]# ./ss3
if: Badly formed number.
root@server1 [/]# cat ss3
#! /bin/csh -f
set X=3.1
set Y=4.1
if ( $X < $Y ) then
echo "\$X=${X}, which is greater than \$Y=${Y}"
endif

Last edited by abefroman; 06-24-2005 at 11:30 AM..
abefroman is offline     Reply With Quote
Old 06-24-2005, 12:02 PM   #2
MoneyCat
LQ Newbie
 
Registered: Jun 2005
Location: USA
Distribution: Ubuntu 5.04
Posts: 10
Thanked: 0
Quote:
Why does it say integer expression expected? How can I compare floats?
This is because the -lt, -gt, -le, -ge, comparisons are only designed for integers. Try using these operators: >, <, >=, <=


Also there is a minor logic problem:
Code:
if [ $X -lt $Y ] # is $X less than $Y ?
then
echo "\$X=${X}, which is greater than \$Y=${Y}"
In the above code, you test if X is LESS THAN Y but then output X is GREATER THAN Y.


Good luck

Last edited by MoneyCat; 06-24-2005 at 12:13 PM..
MoneyCat is offline     Reply With Quote
Old 06-24-2005, 01:20 PM   #3
abefroman
Member
 
Registered: Feb 2004
Location: Chicago
Distribution: CentOS w/Cpanel
Posts: 908
Thanked: 3

Original Poster
It still wont work, got any tips?

root@server1 [/]# cat ss3
#! /bin/csh -f
set X=3.1
set Y=4.1
if [ $X < $Y ] then
echo "wassup"
endif

root@server1 [/]# ./ss3
4.1: No such file or directory.
root@server1 [/]# pico ss3
root@server1 [/]# ./ss3
if: Badly formed number.
root@server1 [/]# cat ss3
#! /bin/csh -f
set X=3.1
set Y=4.1
if ( "$X" < "$Y" ) then
echo "wassup"
endif
abefroman is offline     Reply With Quote
Old 06-24-2005, 01:36 PM   #4
abefroman
Member
 
Registered: Feb 2004
Location: Chicago
Distribution: CentOS w/Cpanel
Posts: 908
Thanked: 3

Original Poster
I tried it in perl but it doesnt store the right value to $a as it does in bash or cshell:
root@server1 [/]# cat ss4
#!/usr/bin/perl
$a=`uptime | awk -F'[, ]*' '{print $11}'`;
#echo "a = $a"
if ( $a > 5.2 ){
print $a;
}


root@server1 [/]# ./ss4
12:34pm up 29 days, 18:11, 1 user, load average: 0.43, 0.32, 0.33
abefroman is offline     Reply With Quote
Old 06-24-2005, 01:54 PM   #5
MoneyCat
LQ Newbie
 
Registered: Jun 2005
Location: USA
Distribution: Ubuntu 5.04
Posts: 10
Thanked: 0
This code below works:

Code:
      1 #!/bin/bash
      2 X=3.1
      3 Y=3.2
      4 empty_string=""
      5
      6 if [ $X < $Y ] # is $X less than $Y ?
      7 then
      8     echo "\$X=${X}, which is less than \$Y=${Y}"
      9 elif [ $X > $y ]
     10 then
     11     echo "\$X=${X}, which is greater than \$Y=${Y}"
     12 fi

Last edited by MoneyCat; 06-24-2005 at 01:55 PM..
MoneyCat is offline     Reply With Quote
Old 06-24-2005, 02:26 PM   #6
perfect_circle
Senior Member
 
Registered: Oct 2004
Location: Athens, Greece
Distribution: Slackware
Posts: 1,773
Thanked: 0
Re: How can I compare floating number in a shell script?

Quote:
Originally posted by abefroman
root@server1 [/]# ./ss3
./ss3: [: 3.1: integer expression expected
root@server1 [/]# cat ss3
#!/bin/bash
X=3.1
Y=3.2
empty_string=""
if [ $X -lt $Y ] # is $X less than $Y ?
then
echo "\$X=${X}, which is greater than \$Y=${Y}"
fi

Why does it say integer expression expected? How can I compare floats?

===========================================
It wont even work in C shell
root@server1 [/]# ./ss3
if: Badly formed number.
root@server1 [/]# cat ss3
#! /bin/csh -f

set X=3.1
set Y=4.1
if ( $X < $Y ) then
echo "\$X=${X}, which is greater than \$Y=${Y}"
endif
As other people have already posted there are ways to work this out but in general case you should know this:
Quote:
Bash does not understand floating point arithmetic. It treats numbers containing a decimal point as strings.
Quote:
When not to use shell scripts

*

Resource-intensive tasks, especially where speed is a factor (sorting, hashing, etc.)
*

Procedures involving heavy-duty math operations, especially floating point arithmetic, arbitrary precision calculations, or complex numbers (use C++ or FORTRAN instead)
*

Cross-platform portability required (use C instead)
*

Complex applications, where structured programming is a necessity (need type-checking of variables, function prototypes, etc.)
*

Mission-critical applications upon which you are betting the ranch, or the future of the company
*

Situations where security is important, where you need to guarantee the integrity of your system and protect against intrusion, cracking, and vandalism
*

Project consists of subcomponents with interlocking dependencies
*

Extensive file operations required (Bash is limited to serial file access, and that only in a particularly clumsy and inefficient line-by-line fashion)
*

Need multi-dimensional arrays
*

Need data structures, such as linked lists or trees
*

Need to generate or manipulate graphics or GUIs
*

Need direct access to system hardware
*

Need port or socket I/O
*

Need to use libraries or interface with legacy code
*

Proprietary, closed-source applications (shell scripts put the source code right out in the open for all the world to see)

Last edited by perfect_circle; 06-24-2005 at 02:30 PM..
perfect_circle is offline     Reply With Quote
Old 06-24-2005, 02:37 PM   #7
sirclif
Member
 
Registered: Sep 2004
Location: south texas
Distribution: fedora core 3,4; gentoo
Posts: 192
Thanked: 0
yea, you can't do very much arithmetic in bash directly. you can pipe some commands to the calculator 'bc', and it will spit out the answer to the standard output.

> echo 3.14 + 5.16 | bc
8.30

as for a comparison, bc has some comparison capability, but you may be able to do something similar with a different tool, by piping it the comparison, and looking at what it returns.
sirclif is offline     Reply With Quote
Old 06-24-2005, 05:54 PM   #8
ahh
Member
 
Registered: May 2004
Location: UK
Distribution: Gentoo
Posts: 293
Thanked: 0
I think awk will do the job:-
Code:
ahh@desktop ~ $ x=3.1; y=3.2; echo "$x $y" | awk '{if ($1 > $2) print $1; else print $2}'
3.2
I'm sure you can adapt it to your script.
ahh is offline     Reply With Quote
Old 08-07-2007, 10:48 AM   #9
wmjosiah
LQ Newbie
 
Registered: Aug 2007
Location: Winchester, NH
Distribution: ubuntu
Posts: 3
Thanked: 0
Actually, that doesn't work exactly. Even if you set X to 3.5, it will still say that X is less than Y.



Quote:
Originally Posted by MoneyCat
This code below works:

Code:
      1 #!/bin/bash
      2 X=3.1
      3 Y=3.2
      4 empty_string=""
      5
      6 if [ $X < $Y ] # is $X less than $Y ?
      7 then
      8     echo "\$X=${X}, which is less than \$Y=${Y}"
      9 elif [ $X > $y ]
     10 then
     11     echo "\$X=${X}, which is greater than \$Y=${Y}"
     12 fi
wmjosiah is offline     Reply With Quote
Old 08-07-2007, 07:25 PM   #10
chrism01
Guru
 
Registered: Aug 2004
Location: Brisbane
Distribution: Centos 5.4
Posts: 7,429
Thanked: 325
Another option in shell is to call expr for doing fp calcs.
I'm curious as to why you think Perl doesn't work, but then I noticed (commented out) 'echo', which is not a perl cmd/keyword.
Try
print "$a\n";

In fact, I'd just call uptime and then do the string parse in perl, instead of piping through awk.
chrism01 is offline     Reply With Quote
Old 08-08-2007, 01:20 PM   #11
makyo
Member
 
Registered: Aug 2006
Location: Saint Paul, MN, USA
Distribution: {Free,Open}BSD, CentOS, Debian, Solaris, SuSE, Xandros
Posts: 566
Thanked: 4
Hi.

Some shells like zsh understand floating point. Here's a sample comparing bash and zsh. It writes a file t1, then asks bash and zsh to execute it:
Code:
#!/bin/sh

# @(#) s1       Compare bash and zsh for arithmetic.

set -o nounset

cat >t1 <<'EOF'

if [ -n "$BASH_VERSION" ]
then
  echo " From bash, version :$BASH_VERSION:"
elif [ -n "$ZSH_VERSION" ]
then
  echo " From zsh, version :$ZSH_VERSION:"
else
  echo " Unknown shell."
fi

float X Y
(( X = 3.0 + 0.5 ))
(( Y = 33.0 / 10.0 ))
if (( $X < $Y )) # is $X less than $Y ?
then
  echo "\$X=${X}, which is less than \$Y=${Y}"
elif (( $X > $Y ))
then
  echo "\$X=${X}, which is greater than \$Y=${Y}"
fi

EOF

echo
bash t1

echo
zsh t1

exit 0
Producing:
Code:
% ./s1

 From bash, version :2.05b.0(1)-release:
t1: line 12: float: command not found
t1: line 13: ((: X = 3.0 + 0.5 : syntax error in expression (error token is ".0+ 0.5 ")
t1: line 14: ((: Y = 33.0 / 10.0 : syntax error in expression (error token is ".0 / 10.0 ")
$X=3, which is less than $Y=33

 From zsh, version :4.2.4:
$X=3.500000000e+00, which is greater than $Y=3.300000000e+00
cheers, makyo
makyo is offline     Reply With Quote
Old 09-12-2008, 05:28 AM   #12
vamsi.coe
LQ Newbie
 
Registered: Sep 2008
Posts: 1
Thanked: 0
Talking May be this will work...

this is a naive way to do this.. but it works


#!/bin/ksh

parm_num=$#

if [ $parm_num -ne 2 ]
then
echo "enter two parameters"
exit 1
fi

d=`echo $1 - $2|bc`
#echo $d
count=`echo $d |grep "-" |wc -l`
if [ $count > 0 ]
then
echo "$2 is greater than $1"
else
echo "$1 is greater than $2"
fi
vamsi.coe is offline     Reply With Quote
Old 09-15-2008, 08:53 AM   #13
jchambers
Member
 
Registered: Aug 2007
Location: California
Distribution: Debian
Posts: 108
Thanked: 0
EDIT: I deleted the prior function as it was flawed...


This one is more complex but will work wit numbers that are not the same length.

It checks if input A is greater that input B.


Code:
#!/bin/sh


a=2.25
b=1.0035

function f_AgtB()
{
	a=$1
	b=$2
	if [ "${a}" != "" -a "${b}" != "" ]
	then
		len_a=${#a}
		len_b=${#b}
		
		if [ $len_a -gt $len_b ]
		then
			b=${b}`f_add_zeros $(( $len_a - $len_b ))`
		else
			a=${a}`f_add_zeros $(( $len_b - $len_a ))`
		fi
		
		a=`echo $a | sed 's/\.//'`
		b=`echo $b | sed 's/\.//'`
		
		if [ $a -gt $b ]
		then
			echo 1
		else
			echo 0
		fi
	fi
}


function f_add_zeros()
{
	i=0
	while [ $i -lt $1 ]
	do
		out=${out}0
		((i++))
	done
	echo $out
}



if [ `f_AgtB $a $b` == 1 ]
then
	echo "CORRECT"
else
	echo "WRONG"
fi


exit

You may want to add some error correction if there is no '.'

Jon

Last edited by jchambers; 09-18-2008 at 03:19 AM..
jchambers is offline     Reply With Quote

Reply

Bookmarks


Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
shell script problem, want to use shell script auto update IP~! singying304 Programming 4 11-29-2005 06:32 PM
How to compare records in two tables in seperate My Sql database using shell script sumitarun Programming 5 04-14-2005 10:45 AM
compare date uusing shell programming please... izza_azhar Programming 7 01-14-2005 08:24 AM
Need text pattern compare script kscott121 Linux - Software 4 05-10-2004 02:13 PM
Help with a Directory Compare Script bullfrog Linux - General 1 02-04-2003 09:05 AM


All times are GMT -5. The time now is 11:27 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
RSS2  LQ Podcast
RSS2  LQ Radio
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: @linuxquestions
Open Source Consulting | Domain Registration