How can I compare floating number in a shell script?
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
How can I compare floating number in a shell script?
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
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;
}
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
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 01:30 PM.
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.
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
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.
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
Just in case anyone is directed to this page, rather than doing some horribly convoluted solution, the following will work on most systems (even ones that dont have bc and perl) - eg many small devices running busybox.
As ahh said - 'awk' is probably your best friend here:
Code:
# Return the value of an operation
float_val() {
echo | awk 'END { print '"$1"'; }'
}
Or more usefully
Code:
# Return status code of a comparison
float_test() {
echo | awk 'END { exit ( !( '"$1"')); }'
}
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.