|
|
How do I compare float / real numbers in a shell script?Hi i am trying to comapre numbers for the biggest among double type of numbers. For example: 0.254, 0.255, 0.564, 0.984, 0.556, 0.6566, and 0.5666. I'm using the following script code: if [ $max -lt $i ] But they all give the error message "integer expression expected". Help! The shell is doing exactly what it should be doing, believe it or not. Shell scripts can't really do proper mathematics, just piddly little simple integer math. So when you give it a number like 0.245 it sees "0" and some gobbledygook that it can't figure out, hence the error message. There are two ways you can solve this. The first is to actually use some sort of more sophisticated mathematical tool like bc to push out the conditional expression, then test its return value to see if your condition was met or not. That's a bit tricky, particularly since bc can be difficult to use. Instead, if indeed your input is always 0.something then I suggest that you can exploit that and simply strip off the "0." prefix, then compare them as integers and get exactly the result you seek. Here's how I'd solve that: #!/bin/sh
max=0 while read value do val="$(echo $value | sed 's/0.//')" if [ $val -gt $max ] then max=$val fi done echo "max value is 0.$max" exit 0 That should do what you seek as long as your input is always well-formed. Really, if this is going to be something that gets a lot of use, I'd probably also add some code that checks to ensure that the inputs all start with "0." to be sure it never breaks too.
More Useful Shell Script Programming Articles:
✔ Secretly capture screenshots on my Mac?
When I used to work on a Linux system, there was a utility we had that would let me take screen captures every...
✔ Parsing "id" strings in a Shell Script?Hello Dave. I need a Bash shell script that creates a directories with the group names automatically when user logs in to the...
✔ Copy and Paste from the Mac OS X Command Line?I am constantly running commands in Terminal.app on my MacBook and then copying and pasting the results into email messages or documents. Yes,...
✔ Script to test line lengths for Twitter compatibility?I've been tasked with writing a series of tweets for a Black Friday marketing campaign and am finding it a bit tricky because...
✔ Shell script to convert lowercase to title case?As part of a project I'm working on, I find myself deep in a Linux shell script, needing to have a subroutine that...
Let's stay in touch!
Sign up for my weekly AskDaveTaylor Newsletter and you'll receive even more tech and gadget help
right to your inbox, along with exclusive news and industry updates. It's good stuff. I promise!
Categorized:
Shell Script Programming
(Article 7141,
Written by Dave Taylor)
Tagged: scripting, shell scripts Previous: Can I get into trouble for downloading illegal files? Next: How do I delete Mac Dashboard widgets? Reader Comments To Date: 20Dave Taylor said, on January 21, 2007 10:23 PM:
(sound of me slapping my head) Doh! You're absolutely right, Paul. I'll dig into this and come up with a different solution, just for completion. :-) Justin K. said, on February 5, 2007 11:43 AM:
This question touches on a limitation of the Bash shell--namely, that it does not understand floating point arithmetic and treats such numbers as strings. Bash documentation even goes on to say this: "When not to use shell scripts So the work-arounds are indirect and perhaps (for some) counter-intuitive. One simple way to fix your code in place is to pipe your input (presumably shell variables) to bc(1), an arbitrary precision calculator language. An example follows below: if [ $max -lt $i ] becomes: if [ $(echo "$max < $i"|bc) -eq 1 ] Where you're using a temporary subshell invocation to calculate and return a value for the test brackets. The comparison against 1 ("-eq 1") is necessary. This is the 'quickest' and smallest solution I can see to your problem, but I'm sure there are (better?) alternative methods. Hope that helps. Danny Howard said, on February 14, 2007 2:36 PM:
Hello. This might make a good interview question for a toolsmith SysAdmin. Here's a script I wrote in answer. It includes flt and fgt functions, that use sort -n, as well as a test harness. Seems to work okay on this LINUX box: #!/bin/sh function fgt () { min=`(echo $LHS ; echo $RHS) | sort -n | head -1` function flt () { min=`(echo $LHS ; echo $RHS) | sort -n | head -1` echo -n "$FUNC $ARG1 $ARG2 ... " if [ $? -eq 0 ]; then true_or_false fgt 1.2 3.4
> ./fgt.sh Dave perhaps you can re-insert the PRE tags. ;) Cheers, Jadu said, on February 26, 2007 5:10 AM:
The one posted by Justin K is really a quick way of doing that, it helped me. Thanks Justin. Tamas Darvas said, on March 14, 2007 6:29 AM:
use simply awk,like: Tamas Darvas said, on March 14, 2007 6:43 AM:
a=1.2 Henk Langeveld said, on March 18, 2007 12:26 PM:
The korn shell ( open source from at&t research ) has had if (( max < i )); then ... ; fi On the other hand, I would not use 'i' for a floating point Plug: ksh93 gets shipped with some versions of unix and linux. Source and binaries can be found at at&t via kornshell.com. Henk abhay vikram singh said, on July 4, 2007 6:34 AM:
sir, and how to find the maximum values among the no.s???? please give the answer with one or two examples. Rizwaan said, on July 20, 2007 1:30 AM:
We can use tr+sort+head or tail to get high and low values #To get Highest value #To get Lowest value #To see for yourself Rizwaan said, on July 20, 2007 1:37 AM:
sorry for the above typo: please use this for Lowest value: #To get Lowest value Shashank said, on July 24, 2007 12:27 AM:
How do I make complex floating operation in a linux script. If I try "100 / 500 | bc" it returns 0, instead of 0.20. Dave Taylor said, on July 24, 2007 6:04 AM:
Right, Shashank. You need to be a bit more tricky because the default setting for "bc" is to have zero digits after the decimal point. What you need to do is feed the statement "scale=2" or similar to get any precision at all. I explain it -- with lots of examples -- in my book Wicked Cool Shell Scripts, which you can learn about at http://www.intuitive.com/wicked/ Samreen said, on August 28, 2007 10:09 AM:
Thanks Justin, that short cut across comparing floating point numbers really helped me... doing that was such a torture.... however just for info is there an alternative way of doing it also ... ? Breno BF said, on July 25, 2008 8:54 AM:
Hi, you can just do: Sumanta said, on March 1, 2009 8:54 AM:
Hi regards Sebastian Castro said, on March 17, 2009 4:03 PM:
If you want to divide two real numbers using 'bc', you have to add the option '-l' (load the math library). If not, sets the precision to zero (set scale=0) and do integer operations. Whip Hubley said, on November 2, 2009 2:25 AM:
Although the bash / bc solution would work fine, KSH is the way forward on this. Just declare your variables as floats with "typeset -F name=variable" and then continue with your calculations. It works a treat. NYCmitch25 said, on January 5, 2010 9:13 AM:
Hey, I've just done the following using expr (found on another website): result=`expr $val1 \> $val2` echo "the values are equal"
# --- calculate (T) --- (basically if time var IS set to the initiated arbitrary value (e.g. 9999) then it needs to have a calculation on it. manjunath.m said, on February 17, 2011 4:40 AM:
how do we compare the max 5 number useing with the while loop in shell programming?????
I do have a comment, now that you mention it!Check This Out Too... |
Recent Entries
Look for Answers
Recommended
All Our Categories
Apple iPad Help
Articles and Reviews Auctions and Online Shopping Blogs and Blogging Building Web Site Traffic Business and Management Computer and Internet Basics d) None of the Above Facebook Help Google Gmail Help Google Plus Help HTML, JavaScript and Web Site Programming Industry News and Trade Shows iPhone and Cell Phone Help iPod, Sony PSP and MP3 Player Help Kindle Fire Help Mac OS X Help Pay Per Click (PPC) Advertising Pinterest Help Search Engine Optimization (SEO) Shell Script Programming Tech Support Video Help The Writing Business Twitter, LinkedIn and Social Network Help Unix and Linux Help Video Game Tips and Help Windows PC Help Find Me on Google+ ADT on G+ |
If you simply strip off the "0.", then "0.984" will appear to be a smaller integer than "0.6566", but if you compare the originals as strings (dictionary order), then the result would be correct. Unfortunately, neither of these approaches works when you have different numbers of digits before and after the decimal point. Then you'd have to "normalize" by adding leading or trailing zeroes depending on whether you want to use string comparison or integer comparison.