LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
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
  Search this Thread
Old 08-11-2011, 09:50 AM   #1
devUnix
Member
 
Registered: Oct 2010
Posts: 606

Rep: Reputation: 59
Dealing with Real Numbers in Bash


Hi,


let, expr, and bc - all can be used for Mathematical calculations but the first two commands fail when there is a real number or fractional number to deal with. bc does not help when we need multiplication and division operations.

Let's take this example:

Code:
$ echo "10000 * 100 / 15000" | bc
$ 66
That is not what we expect.

But this one works fine:

Code:
$ echo "10000 - 10.99" | bc
$ 9989.01
But I need to do multiplication and division operations and the resultant values / numbers can be real ones.

How to achieve it in bash?

Well, I do know that Shell Script or Bash can't help us much with Mathematical calculations that require (some or large) precision.

So, wherever in my script I need to do some calculations, what tool or approach should I employ?
 
Old 08-11-2011, 10:00 AM   #2
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
This will get you what you want, if you adjust the value of scale as required
Code:
echo "scale=2; 10000 * 100 / 15000" | bc
I wonder how bc chooses the scale to use in each of the OP cases.
 
Old 08-11-2011, 10:23 AM   #3
devUnix
Member
 
Registered: Oct 2010
Posts: 606

Original Poster
Rep: Reputation: 59
Error in Comparing Real Numbers

Quote:
Originally Posted by catkin View Post
This will get you what you want, if you adjust the value of scale as required
Code:
echo "scale=2; 10000 * 100 / 15000" | bc
Thanks!

I just did read about the scale thing on a manual online but did not give it a try.

Well, another problem is born now. "if [ $result -ge 10 ]" (for example) fails because of the obvious reason that it expects an integer expression.

So, 66.66 will not be compared with 10 in the above case.

Converting a decimal value into a string and then making a comparison is also not logical and correct every time.


However, I found some ways here:

http://www.unix.com/shell-programmin...l-numbers.html

Last edited by devUnix; 08-11-2011 at 10:26 AM.
 
Old 08-11-2011, 10:29 AM   #4
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
A solution is to use bc to do such comparisons. From the bc man page: "Relational expressions are a special kind of expression that always evaluate to 0 or 1, 0 if the relation is false and 1 if the relation is true".

Unfortunately bash's usage of 0 and 1 (not 0) for true and false results in some counter-intuitive bits of code like:
Code:
[[ $( echo '1 > 2' | bc ) ]] && echo false || echo true
 
Old 08-11-2011, 10:39 AM   #5
lyle_s
Member
 
Registered: Jul 2003
Distribution: Slackware
Posts: 392

Rep: Reputation: 55
Quote:
Originally Posted by devUnix View Post
Code:
$ echo "10000 * 100 / 15000" | bc
$ 66
Is this what you're looking for?:
Code:
$ echo "10000 * 100 / 15000" | bc -l
$ 66.66666666666666666666
Lyle.
 
Old 08-11-2011, 10:42 AM   #6
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Quote:
Originally Posted by catkin View Post
Code:
[[ $( echo '1 > 2' | bc ) ]]
I don't know about you, but $? is 0 whether or not '1 < 2' or '1 > 2' for me.
Code:
[[ $( echo '1 > 2' | bc ) -ne 0 ]] && echo true || echo false
Kevin Barry

PS I believe what you had is shorthand for -n.

Last edited by ta0kira; 08-11-2011 at 10:57 AM.
 
Old 08-11-2011, 12:18 PM   #7
MTK358
LQ 5k Club
 
Registered: Sep 2009
Posts: 6,443
Blog Entries: 3

Rep: Reputation: 723Reputation: 723Reputation: 723Reputation: 723Reputation: 723Reputation: 723Reputation: 723
Quote:
Originally Posted by ta0kira View Post
I don't know about you, but $? is 0 whether or not '1 < 2' or '1 > 2' for me.
That checks bc's output, not its exit code.

EDIT: After trying this, I'm not sure:

Code:
$ if [[ 0 ]]; then echo true; fi
true
$ if [[ 1 ]]; then echo true; fi
true
EDIT2: I tried this, too:

Code:
$ if [[ $(false) ]]; then echo true; fi
$ if [[ $(true) ]]; then echo true; fi
$ if [[ $(echo 1) ]]; then echo true; fi
true
$ if [[ $(echo 0) ]]; then echo true; fi
true
$ if [[ $(echo fgdfgsdf) ]]; then echo true; fi
true
It looks like it's checking whether the string is not empty, not the exit code or numeric value.

Last edited by MTK358; 08-11-2011 at 12:21 PM.
 
Old 08-11-2011, 01:14 PM   #8
H_TeXMeX_H
LQ Guru
 
Registered: Oct 2005
Location: $RANDOM
Distribution: slackware64
Posts: 12,928
Blog Entries: 2

Rep: Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301
I recommend you try awk. It can do a lot of math, and works more like C.
 
Old 08-11-2011, 01:28 PM   #9
SigTerm
Member
 
Registered: Dec 2009
Distribution: Slackware 12.2
Posts: 379

Rep: Reputation: 234Reputation: 234Reputation: 234
Quote:
Originally Posted by devUnix View Post
Let's take this example:

Code:
$ echo "10000 * 100 / 15000" | bc
$ 66
That is not what we expect.
from man bc:

Quote:
There are four special variables, scale, ibase, obase, and last. scale defines how some operations use digits after the decimal point. The default value of scale is 0.
...
If bc is invoked with the -l option, a math library is preloaded and the default scale is set to 20. The math functions will calculate their results to the scale set at the time of their call.
I.e. use
Code:
echo "10000 * 100 / 15000" | bc -l
 
Old 08-11-2011, 02:15 PM   #10
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
Quote:
Originally Posted by MTK358 View Post
It looks like it's checking whether the string is not empty, not the exit code or numeric value.
Thanks for the investigation and determining that I was wrong MTK358

Apologies to everyone else for peddling a bum steer
 
  


Reply



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
How can i subtract two non-real (aka decimal'd) numbers via bash onesikgypo Programming 3 04-28-2010 11:55 AM
Bash script: Dealing with program input from a pipe sleeper0110 Linux - Software 5 04-28-2009 03:41 PM
LXer: Linux dark matter obscures real Firefox user numbers LXer Syndicated Linux News 0 12-03-2007 08:50 PM
Dealing with text in bash scripts Skute Programming 6 03-16-2004 02:58 AM
post AIM sn's + ICQ numbers for real time help mp3province Linux - Software 4 04-10-2003 12:05 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 06:55 AM.

Main Menu
Advertisement
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
Twitter: @linuxquestions
Open Source Consulting | Domain Registration