Looking through my site logs, I realise that many people who find the GNU bc page are looking for something that isn't there, or they don't see it immediately when the page loads, so they think it's not there. The purpose of this page, despite it being practically verbatim from its predecessor, is here to help rectify that.
Without further ado, here are some of the questions asked of search engines that people haven't found the answer to on the GNU bc page:
I reckon this is a trick question - do you guys want to use bc or not? :) Okay... Lets assume both and work from there:
You really honestly and truthfully don't want to do this, surely? The bash shell is only capable of integer arithmetic, so even if you could take a square root, you'll only get the integer portion of the answer... i.e. sqrt(10) = 3 to the nearest whole number. If that's all you need, then this shell function is for you:
sqrt() { local x=$1 s=$1 os=0;while ((s!=os));do os=$s;s=$(((s+x/s)/2));if((s>os));then s=$os;fi;done;echo $s; }
That's all on one line.
Once you've entered the above into a script or your interactive session, the command
sqrt {number} will output the square root of {number}. e.g.
sqrt 123456 will print 351.
Be warned though, the above contains no checking for negative numbers, and so the function just returns the same negative number!
The simplest way to do this is to pipe some bc syntax to bc -l:
echo 'sqrt({number})' | bc -l
...making the obvious replacement of {number}. Yes. It's that simple!
If you've been paying attention class, the answer to this has already been used in the previous answer!
bc has its own built in sqrt() function. You don't even need to
include the standard library - it's right there when you run the program... Which leads
us on to the next question...
It concerns me greatly the number of people who don't know about the scale
variable in bc. With scale, the number of decimal places of
floating point precision can be set. Including the standard library (with the
-l flag) automatically sets the scale to 20. This site's
funcs.bc library sets the same to 50 for increased accuracy.
For instance; The example from the question before last might have been written:
echo 'scale=20;sqrt({number})' | bc
Note the lack of the -l flag this time. Also; Changing that 20 will change
the number of decimal places in the answer printed.
Again... not sure whether the requestor wants bash or bc code, so it's twice the work for me :):
Bearing in mind that bash is integer-only, this shell function will return the rounded down logarithm in bash:
log(){ local x=$1 n=2 l=-1;if [ "$2" != "" ];then n=$x;x=$2;fi;while((x));do let l+=1 x/=n;done;echo $l; }
As before, it's all on one line.
Once you've entered the above into a script or your interactive session, the command
log {number} will output the logarithm of {number} to base 2.
e.g. log 123456 will print 16 (even though the log to base 2
of 123456 is nearer to 17!)
The 'clever' bit is that the command log {n1} {n2}
will output the logarithm of {n2} to base {n1}, so log 10 10000
will print 4, and log 3 9923 will print 8, etc.
Beware again - this works only when fed positive integers. Anything else is not checked for and may cause this function to behave bizarrely.
Guess what? You can pipe some bc syntax to bc -l!:
echo 'l({number})' | bc -l
or
echo 'l({n1})/l({n2})' | bc -l
...making the obvious replacements.
The easiest way to do a cube root in bc is to use the pow() and
root() functions from this site's
funcs.bc library; pow({number},1/3) and
root({number},3) both achieving the required result. ;)
Of course, you may just want to use the following quick-and-dirty trick that both of those functions are based upon. Again, this example is for the bash shell:
echo 'e(l({number})/3)' | bc -l
This works on the mathematical principle that:
n√x = x(1/n) = e(ln x)/n
In bc you might like to use this to write your own cube root function:
define cbrt(x) { return e(l(x)/3)) }
And then use it as you would the built in sqrt().
As you might guess then, the e() and l() used above are the
GNU bc exponential and natural logarithm functions respectively. Both are only
available as part of the standard library, so the -l flag is absolutely
essential for them to be usable.
You should also be aware that the accuracy of the cube root function, and indeed any
function written in bc, is directly affected by the value of the
scale variable.
If you've found your way across the internet to this question, chances are you're
looking for bc's equivalent of C's ^ operator.
Fun fact: no such thing exists in bc.
In bc, the up-arrow operator is used for integer exponentiation, that is, 2^x returns a power of 2 and not x with bit 2 flipped. If you're looking for equivalents to the bitwise operators for XOR as well as AND, OR and a few more exotic relatives, check out this site's logic.bc, and its relatives which contain functions to perform each of these.
If you're looking for a logical XOR to put in an if statement, like
logical && and ||, try using != and surrounding
your conditions with brackets. e.g.:
c=0;if((a==1)!=(b==2)){c=3}
Will set c to 3, if a is 1 or b is 2, but not if a is 1 and b is 2 at the same time
(Once upon a time, this was the secret to the internals of the
logic.bc xor() function,
but this has been superseded by a faster algorithm.)
When performing some - usually division-related - calculations in bc, especially
with the scale variable set high, the answer returned
to the console (or stored in a variable) has many trailing zeroes at the end. e.g.
the code scale=20;7/4 will cause 1.75000000000000000000
to be printed as the result.
Often this is cumbersome and makes 'obvious' numbers harder to read. The solution is the following function:
define trunc(x){auto os;os=scale;for(scale=0;scale<=os;scale++)if(x==x/1){x/=1;scale=os;return x}}
With this function you can say things like scale=20;q=7/4;q=trunc(q);q or
simply scale=20;trunc(7/4), both of which will print 1.75 as
expected.
An improved version of this, which can also deal with trailing 9's (in decimal) can be
found in outputformatting.bc, and this also
contains many other output formatting functions, including two similar to C's
printf().