Saturday, 16 July 2016

bc - scientific calculation


When writing this post, I will assume that - 

1 You can do scientific operation 
2. You are aware of bc, if not, if you can see this post - bc

We will learn our next arithmetic operation. With this operation, we can change any number from one base to another. For this, we will use the other two variables obase and ibase like scale . If you do not know what is a variable, keep in mind, it's a placeholder whose value can be changed and while bc calculates it shows the answer based on the values ​​of these variables. Variables are important for programming and if you want to continue your studies with bc, you have to learn bc programming eventually , so gradually knowing these small parts is good. obase is used to indicate in which base output will be shown. The same way ibase is used to indicate in which base the input is being provided to bc. When bc is run, the value of both ibase and obase is 10. ibase take values ​​from 2 to 16 and obase from 2 to 999. But for day to day work, 2 to 16 is enough, and here also we will calculate using the base from 2 to 16. Let's try to understand the matter with a few examples -

ibase = 2

0
0

1
1

10
2

11
3

100
4

101
5

110
6

111
7

78
3

79
3

11
3

70
2

90
2

10
2

01
1

45
3

11
3

61
3

111
7

789
7

654
7

789
7

Or
ibase
3


obase
10

10
3

11
4

12
5

13
5

14
5

15
5

21
7

10
3

01
1

31
7

21
7

There are two things to note here, when we type ibase or obase , we see one value, actually these are the value of those variables which means, the input in the second case is given at 3 base and the output is shown at 10 base. One more thing is to be noticed, in both cases, when we input more than the digits of a base, it takes the highest value digit of that base. When ibase was 3 then15 was 5 (the highest digit is 2 in base 3, so bc took 15 as 12, on base 10 which is 5), same with ibase  when 2 is the base and input was 78 and 79, it was taken as 11, which in base 10 is 3.

Let's see some examples of obase -
obase = 16

ibase
A

obase
10

17
11

15
F

16
10

14
E

125
7D

67
43

546
222

554
22A

668
29C

4854
12F6

ADF
3E7

Do not be worried seeing the first two lines, 16 shows 10 in base 16 and 10 shows A. Here also you can see I gave the input as ADF which took the input as the 999 and showed the hexadecimal 3E7 as answer. 

This time we will change the two variables together and change from binary to hexadecimal -
Totan @ home-computer ~ $ bc
Bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
Details For type  ` warranty ' .

obase = 16
ibase = 2

obase
10

ibase
2

11
3

1111
F

11111111
FF

10101100
AC

1011011010010100101
5B4A5

10101001
A9

010111011010101010010100010100
176AA514

11 + 11
6

1101 + 1101
1A

11 + 101
8

1101 + 101
12

111 + 10
9

Not only changing one number from one base to another, we can add two numbers in a base and change the result to show on another base. We'll take a look at some more examples -
Totan @ home-computer ~ $ bc
Bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
Details For type  ` warranty ' .

obase = 16
ibase = 2

obase
10

ibase
2

sqrt ( 100 )
2

sqrt ( 11 )
1

scale = 10

sqrt ( 11 )
1.BA

sqrt ( 1001 )
3.00

sqrt ( 1111 )
3.DE

sqrt ( 1111 )
3.DE

sqrt ( 11111111 )
F.F5

11-1
2

11-11111
-1C

11 * 11
9

10 * 01
2

10/1
2.00

1001/1101
.B0

In addition to base changes, bc does some scientific operations, such as sine, cosine, logarithm, arctangent, exponential etc. 
For this we need to type bc -l in our command line. -l is an option that helps bc to load all operations in mathematical libraries. Some of the operations are in the library -
  • S (x): The sine of x, x is in radians 
  • C (x): The cosine of x, x is in radians.
  • A (x): The arctangent of x, arctangent returns radians.
  • L (x): The natural logarithm of x.
  • E (x): The exponential function of raising e to the value x.
  • J (n, x): The bessel function of integer order n of x
Because bc can not calculate all types of trigonometry operations, so we will know some identities -
  • tan (x) = sin (x) / cos (x)
  • cot (x) = cos (x) / sin (x)
  • Sec (x) = 1 / cos (x)
  • cosec (x) = 1 / sin (x)
  • arcsin ( x ) = 2 * arctan (x / (1 + sqrt (1-x ^ 2)))
  • arccos ( x ) = pi / 2 - arcsin ( x ) = pi / 2 - 2 * arctan (x / (1 + sqrt (1-x ^ 2)))
  • arccot ​​(x) = pi / 2 - arctan (x) 
  • arccsc (x) = arcsin (1 / x) = 2 * arctan ((1 / x) / (1 + sqrt (1- (1 / x) ^ 2)))
  • arcsec (x) = arccos (1 / x) = pi / 2 - arcsin (1 / x ) = pi / 2 - 2 * arctan ((1 / x) / (1 + sqrt (1- (1 / x) ^ 2)))
  • degree = radian * (180 / (22/7))
  • radian = degree * ((22/7) / 180)
With the help of these identities, we can calculate the value of all the trigonometric operations using a (x), s (x), c (x) operation. This time we will take a look at these operations with a few examples -

Notice a few things -

  • Now the value of scale is 20. When wee run bc -l, it automatically sets scale to 20 
  • When we use s, c operations, we change from degree to radian and provide input.
  • There is no operation to determine tan (x), sec (x), cot (x) and cosec (x), so we can calculate the value of tan, cot, sec and cosec with the help of an identity using s and c.
  • Valid values ​​are more important for delicate calculations. So you will pay more importance to python, java, matlab, etc. for very accurate calculation than bc.  
    Now we will take a look at some examples of arctangent -
    a ( 9999999999 )
    1.57079632669489661922
    
    a ( 9999999999 ) * ( 180 / ( 22/7 ))
    89.96378961979862455540
    
    a ( 0 )
    0
    
    a ( 1 )
    .78539816339744830961
    
    a ( 1 ) * ( 180 / ( 22/7 ))
    44.98189481276294864133
    

    The first answer we see in the radian unit and we are changing it to degree with the help of a formula. 
    With the help of a(x), I will find out the value of arcsin -
    x = 1
    
    2 * a ( x / ( 1 + sqrt ( 1-x ^ 2 )))
    1.57079632679489661922
    
    2 * a ( x / ( 1 + sqrt ( 1-x ^ 2 ))) * ( 180 / ( 22/7 ))
    89.96378962552589728267
    A ( 1 )
    .78539816339744830961
    
    a ( 1 ) * ( 180 / ( 22/7 ))
    44.98189481276294864133
    
    x = 0.5
    
    2 * a ( x / ( 1 + sqrt ( 1-x ^ 2 )))
    .52359877559829887306
    
    2 * a ( x / ( 1 + sqrt ( 1-x ^ 2 ))) * ( 180 / ( 22/7 ))
    29.98792987517529909346
    
    x = 0
    
    2 * a ( x / ( 1 + sqrt ( 1-x ^ 2 )))
    0
    
    2 * a ( x / ( 1 + sqrt ( 1-x ^ 2 ))) * ( 180 / ( 22/7 ))
    0
    

    Look at one thing, we're giving value of x like scale or obase or ibase. That means we're using x as a variable. In this way we can write complex formulas easily and can run repeatedly and by giving different values ​​of x, we can apply the same formula over different input values. 

    Now we will calculate arccos (x) values -
    x = 1
    
    (( 22/7 ) / 2 ) - 2 * a ( x / ( 1 + sqrt ( 1-x ^ 2 )))
    .00063224463367480935
    
    ((( 22/7 ) / 2 ) - 2 * a ( x / ( 1 + sqrt ( 1-x ^ 2 )))) * ( 180 / ( 22/7 ))
    .03621037447410271731
    
    x = 0
    
    (( 22/7 ) / 2 ) - 2 * a ( x / ( 1 + sqrt ( 1-x ^ 2 )))
    1.57142857142857142857
    
    ((( 22/7 ) / 2 ) - 2 * a ( x / ( 1 + sqrt ( 1-x ^ 2 )))) * ( 180 / ( 22/7 ))
    89.99999999999999999999
    
    x = 0.5
    
    (( 22/7 ) / 2 ) - 2 * a ( x / ( 1 + sqrt ( 1-x ^ 2 )))
    1.04782979583027255551
    
    ((( 22/7 ) / 2 ) - 2 * a ( x / ( 1 + sqrt ( 1-x ^ 2 )))) * ( 180 / ( 22/7 ))
    60.01207012482470090653
    

    This time we will see some arccot's value--
    x = 1
    
    (( 22/7 ) / 2 ) - a ( x )
    .78603040803112311896
    
    ((( 22/7 ) / 2 ) - a ( x ) * ( 180 / ( 22/7 ))
    45.01810518723705135865
    
    x = 0
    
    (( 22/7 ) / 2 ) - a ( x )
    1.57142857142857142857
    
    ((( 22/7 ) / 2 ) - a ( x ) * ( 180 / ( 22/7 ))
    89.99999999999999999999
    

    Now we will see how we can calculate the value of arcsec with the help of identity -
    x = 2
    
    2 * a (( 1 / x ) / ( 1 + sqrt ( 1- ( 1 / x ) ^ 2 )))
    .52359877559829887306
    
    ( 2 * a (( 1 / x ) / ( 1 + sqrt ( 1- ( 1 / x ) ^ 2 )))) * ( 180 / ( 22/7 ))
    29.98792987517529909346
    
    x = 1
    
    2 * a (( 1 / x ) / ( 1 + sqrt ( 1- ( 1 / x ) ^ 2 )))
    1.57079632679489661922
    
    ( 2 * a (( 1 / x ) / ( 1 + sqrt ( 1- ( 1 / x ) ^ 2 )))) * ( 180 / ( 22/7 ))
    89.96378962552589728267
    
    x = 4
    
    2 * a (( 1 / x ) / ( 1 + sqrt ( 1- ( 1 / x ) ^ 2 )))
    .25268025514207865348
    
    ( 2 * a (( 1 / x ) / ( 1 + sqrt ( 1- ( 1 / x ) ^ 2 )))) * ( 180 / ( 22/7 ))
    14.47168733995541379023
    

    Finally we conclude this post by evaluating some of the arcsec values ​​-
    pi = 22/7
    
    x = 99999999999999999
    
    pi / 2 - 2 * a (( 1 / x ) / ( 1 + sqrt ( 1- ( 1 / x ) ^ 2 )))
    1.57142857142857141857
    
    ( pi / 2 - 2 * a (( 1 / x ) / ( 1 + sqrt ( 1- ( 1 / x ) ^ 2 )))) * ( 180 / ( 22/7 ))
    89.99999999999999942726
    
    
    x = 4
    
    pi / 2 - 2 * a (( 1 / x ) / ( 1 + sqrt ( 1- ( 1 / x ) ^ 2 )))
    1.31874831628649277509
    
    ( pi / 2 - 2 * a (( 1 / x ) / ( 1 + sqrt ( 1- ( 1 / x ) ^ 2 )))) * ( 180 / ( 22/7 ))
    75.52831266004458620976
    
    x = 0.2
    
    pi / 2 - 2 * a (( 1 / x ) / ( 1 + sqrt ( 1- ( 1 / x ) ^ 2 )) 
    Runtime error ( func = ( main ) , adr = 26 ) : Square root of a negative Number
    
    x = 5
    
    pi / 2 - 2 * a (( 1 / x ) / ( 1 + sqrt ( 1- ( 1 / x ) ^ 2 )))
    1.37007065063824063713
    
    ( pi / 2 - 2 * a (( 1 / x ) / ( 1 + sqrt ( 1- ( 1 / x ) ^ 2 )))) * ( 180 / ( 22/7 ))
    78.46768271837196376296
    

    Here you will notice two things. I will not tell you anything about them, think about it and try to find answers.
    Next we'll see some more scientific calculations.

    bc - logarithm, exponential and function

    We have seen how to change a number to a different base, we've changed some numbers from one base to another. We have seen how we can perform various trigonometric operations. We have seen how to calculate different trigonometric values ​​with the help of a single trigonometric operation and identity. Now we will know how to calculate the value of logarithm. Again, I've to say that bc can only evaluate the value of natural logarithm or ln, we will use the help of identities for determining the logarithm of another base, so we will keep some formulas in mind -
    • log   (x) = ln (x) / ln (y)
    • ln (e ^ x) = x 
    • e ^ ln (x) = x
    Now we will look at some examples on how to calculate logarithm and exponential using bc -
    Totan @ home-computer ~ $ bc -l
    Bc 1.06.95
    Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
    This is free software with ABSOLUTELY NO WARRANTY.
    Details For type  ` warranty ' .
    
    x = 1
    
    e ( x )
    2.71828182845904523536
    
    l ( x )
    0
    
    l ( 10 )
    2.30258509299404568401
    
    l ( x ) / l ( 10 )
    0
    
    x = 100
    
    l ( x ) / l ( 10 )
    2.00000000000000000000
    
    x = 100000000
    l ( x ) / l ( 10 )
    8.00000000000000000002
    
    x = 15
    
    e ( l ( x ))
    14.99999999999999999990
    
    l ( e ( x ))
    14.99999999999999999999
    
    l ( x )
    2.70805020110221006599
    
    x = 16
    
    l ( x )
    2.77258872223978123766
    
    l ( x ) / l ( 2 )
    4.00000000000000000002
    
    l ( x ) / l ( 4 )
    2.00000000000000000000
    

    If we want to run a formula repeatedly for different values, we have to repeatedly change the value of the variable (in this case x) and then run the formula again. It may not be very difficult for small calculations, but it is very difficult for bigger formulas. So we will learn a new way to solve such problems and we'll go one step further in programming, and will see how to write functions in bc. In simple language function is a programming block, where we write together one or more line of programs and name it according to our choice and later provide input to the function to get result. Now we will see how to write the function and provide input to it.
    define log ( x ) {  return l ( x ) / l ( 10 ) ; }
    
    log ( 10000 )
    4.00000000000000000001
    
    define log ( x, y ) {  return l ( y ) / l ( x ) ; }
    
    
    log ( 2, 8 )
    3.00000000000000000002
    
    log ( 625, 5 )
    .25000000000000000000
    
    log ( 1024, 2 )
    .09999999999999999999
    
    log ( 2, 1024 )
    10.00000000000000000010
    
    log ( 5, 625 )
    4.00000000000000000000
    
    log ( 10 ) 
    Runtime error ( func = ( main ) , adr = 8 ) : Parameter number match
    

    Reading the code carefully, we can understand what the function is doing. In the first case, it evaluates log base 10 value. After that, we change the function to accept more input value and we are computing the value of log x (y) in the changed function . 
    Now notice the last line, when we change the function, and we provide it only one input value, it does not work, because now the function is taking two values ​​as input. These input values ​​are called parameters in programming language. Now think about how beautiful the trigonometric formulas could be with the use of functions. I will not do them for you. This work is for you, changing the trigonometric formulas in a well-formed function and use them. 

    After this, it is easy to work but you will notice that when you come out of bc and type bc again, you will lose the written functions of the previous session. So, you really want to save all your work and use them later. 

    But for that you have to know some editor and file system. If you have any idea about these, then you can proceed in the next section - bc - files and programming. Otherwise, check for some file editor and file system details of Unix/Linux

    bc - Files and Programming

    We have seen how we can calculate different values of different mathematical operations with the help of bc and in bc how we can apply the same formula to different values ​​with the help of function. But we saw that we can not run our functions second time after bc stops running, so we will now see how we can save them in a file and run them across different bc sessions. bc can take multiple files as input at the same time. Now we will take a look at how to create a file, write some function in it and use it in bc.
    totan @ home-computer ~ $ mkdir bc
    totan @ home-computer ~ $ cd bc
    totan @ home-computer ~ / bc $ vi custom_lib.bc
    

    I first created another directory named bc in my home directory and created a file named custom_lib.bc and in that file I have saved the following lines -
    scale = 40;
    pi = 22/7;
    define tan ( x )  {return s ( x ) / c ( x ) ; }
    

    Now when we run bc we will input the file and run our tan function -
    totan@Home-Computer ~/bc $ bc custom_lib.bc
    bc 1.06.95
    Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
    This is free software with ABSOLUTELY NO WARRANTY.
    For details type `warranty'. 
    tan(90)
    Runtime error (func=tan, adr=4): Function s not defined.
    



    What happened ? 
    Why an error ?
    We only provided input of our file but when it runs, it needs s and c function, which is written in math library but we did not run bc -l, we just input our file to bc, so this error shows. This time we will run properly and see what happens -
    totan@Home-Computer ~/bc $ bc -l custom_lib.bc 
    bc 1.06.95
    Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
    This is free software with ABSOLUTELY NO WARRANTY.
    For details type `warranty'. 
    
    pi
    3.1428571428571428571428571428571428571428
    
    scale
    40
    
    tan(pi/2)
    -1581.6660411069837079729290816982181591162519

    Let us now convert all the trigonometric formulas in the form of function and save it to the file -
    scale = 40;
    pi = 22/7;
    define degree ( radian )  {  return radian * ( 180 / ( 22/7 )) ; } 
    define radian ( degree )  {  return degree * (( 22/7 ) / 180 ) ; }
    
    define sin ( x )  {  return s ( x ) ; } 
    define cos ( x )  {  return c ( x ) ; } 
    define tan ( x )  {  return sin ( x ) / cos ( x ) ; } 
    define cot ( x )  {  return cos ( x ) / sin ( x ) ; } 
    define sec ( x )  {  return 1 / cos ( x ) ; } 
    define cosec ( x )  {  return 1 / sin ( x ) ; }
    
    define arctan ( x )  {  return a ( x ) ; } 
    define arcsin ( x )  {  return 2 * arctan ( x / ( 1 + sqrt ( 1-x ^ 2 ))) ; } 
    define arccos ( x )  {  return pi / 2 - arcsin ( x ) ; } 
    define arccot ( x )  {  return pi / 2 - arctan ( x ) ; } 
    define arccsc ( x )  {  return arcsin ( 1 / x ) ; } 
    define arcsec ( x )  {  return arccos ( 1 / x ) ; }
    

    This time we have a full trigonometric library and we will use it -
    totan@Home-Computer ~/bc $ bc -l custom_lib.bc 
    bc 1.06.95
    Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
    This is free software with ABSOLUTELY NO WARRANTY.
    For details type `warranty'. 
    
    pi
    3.1428571428571428571428571428571428571428
    
    degree(pi)
    179.9999999999999999999999999999999999999997
    
    degree(pi/2)
    89.9999999999999999999999999999999999999998
    
    radian(1.57)
    .0274126984126984126984126984126984126983
    
    radian(89.99999999999999999999999999999998)
    1.5714285714285714285714285714285710793596
    
    radian(179.99999999999999999999999999999998)
    3.1428571428571428571428571428571425079256
    
    tan(pi)
    .0012644899412946341567363163883638298730
    
    cot(pi)
    790.8327044311328950385320768793316826822764
    
    sin(pi/2)
    .9999998001333682524818408858972908885417
    
    cos(pi/2)
    -.0006322445915532736545183507752145567302
    
    cos(pi/4)
    .7068832136245869031428194525782683945745
    
    sin(pi/4)
    .7073302780849810594563841044291318942708
    
    sec(pi/4)
    1.4146608389134590576641966960370960477362
    
    
    cosec(pi/4)
    1.4137667098139641735735833689442185007077
    
    cos(radian(30))
    .8659200104474300306216745503726937450452
    
    cos(pi/6)
    .8659200104474300306216745503726937450443
    
    arccos(0.8659200104)
    .5244417685380240683932317158122716760510
    
    degree(arccos(0.8659200104))
    30.0362103799050148261578164510664687192850

    In this way, we can use the file to build our own libraries. 
    But after all, you feel that what is the use of doing all these things if we can not properly calculate all the values. Well you may not return proper output for all the input, but you can return proper output for some special inputs, such as cos (pi / 2), sin (pi / 2) etc. You can return the correct value for these special input parameter values. For that you have to learn a little more programming. Let's see how we can return proper output for a particular input. 
    To accommodate this change, I've changed the previous file -
    scale=40;
    pi=22/7;
    
    define degree(radian) { return radian * (180/(22/7)); }
    define radian(degree) { return degree * ((22/7)/180); } 
    
    define sin(x) { 
     if (x == pi/2){
      return 1;
     } else {
      return s(x);
     }
    }
    define cos(x) {
     if (x == pi/2){
                    return 0;
            } else {
      return c(x); 
     }
    }
    define tan(x) {
     if (x == pi/2){
                    return 10^40;
            } else {
      return sin(x)/cos(x); 
     }
    }
    define cot(x) { 
     if (x == 0){
                    return 10^40;
            } else {
      return cos(x)/sin(x); 
     }
    }
    define sec(x) { 
     if (x == pi/2){
                    return 10^40;
            } else {
      return 1/cos(x); 
     }
    }
    define cosec(x) { 
     if (x == 0){
                    return 10^40;
            } else {
      return 1/sin(x); 
     }
    }
    
    define arctan(x) { return a(x); }
    define arcsin(x) { return 2*arctan(x/(1+sqrt(1-x^2))); }
    define arccos(x) { return pi/2 -  arcsin(x); }
    define arccot(x) { return pi/2 - arctan(x); }
    define arccsc(x) { return arcsin(1/x); }
    define arcsec(x) { return arccos(1/x); }
    
    

    Now, see I used if for every special input, it is actually a keyword that helps bc to indicate that we are checking for a particular situation, and if that particular situation arises, we will run the program in one way, otherwise run the program in another way. We will write this special situations in parentheses. In case of special circumstances such as tan, when we input pi/2, we try to return infinity (in fact infinity is not possible in real life, so we're returning 10^40, considering it large enough for our calculation); in another case we are returning sin(x)/cos(x)In the same way sin, cos, cot, sec, cosec each have its own special input values where we need special return rather than the calculated output. We will now calculate some values ​​by running bc -
    totan@Home-Computer ~/bc $ bc custom_lib.bc -l
    bc 1.06.95
    Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
    This is free software with ABSOLUTELY NO WARRANTY.
    For details type `warranty'. 
    
    sin(0)
    0
    
    sin(pi/2)
    1
    
    sin(pi/3)
    .8662360750607195043408695349267950975451
    
    sin(pi/4)
    .7073302780849810594563841044291318942708
    
    sin(pi/6)
    .5001825021996697823102745005453209790920
    
    cos(pi/6)
    .8659200104474300306216745503726937450443
    
    cos(0)
    1.0000000000000000000000000000000000000000
    
    cos(pi/2)
    0
    
    tan(pi/2)
    10000000000000000000000000000000000000000
    
    cot(0)
    10000000000000000000000000000000000000000
    
    tan(pi/4)
    1.0006324445845895900615571597665295784979
    
    cot(pi/4)
    .9993679551487537983317012806569424613799

    But after that also we can see that the value of tan(pi/4 ) or  cot(pi/4) is not accurate, so we will change the file again -
    scale=40;
    pi=22/7;
    
    define degree(radian) { return radian * (180/(22/7)); }
    define radian(degree) { return degree * ((22/7)/180); } 
    
    define sin(x) { 
     if (x == pi/2){
      return 1;
     } else {
      return s(x);
     }
    }
    define cos(x) {
     if (x == pi/2){
                    return 0;
            } else {
      return c(x); 
     }
    }
    define tan(x) {
     if (x == pi/2){
                    return 10^40;
     } else if (x == pi/4){
                    return 1;
            } else {
      return sin(x)/cos(x); 
     }
    }
    define cot(x) { 
     if (x == 0){
                    return 10^40;
            } else if (x == pi/4){
      return 1;
     } else {
      return cos(x)/sin(x); 
     }
    }
    define sec(x) { 
     if (x == pi/2){
                    return 10^40;
            } else {
      return 1/cos(x); 
     }
    }
    define cosec(x) { 
     if (x == 0){
                    return 10^40;
            } else {
      return 1/sin(x); 
     }
    }
    
    define arctan(x) { return a(x); }
    define arcsin(x) { return 2*arctan(x/(1+sqrt(1-x^2))); }
    define arccos(x) { return pi/2 -  arcsin(x); }
    define arccot(x) { return pi/2 - arctan(x); }
    define arccsc(x) { return arcsin(1/x); }
    define arcsec(x) { return arccos(1/x); }

    In this case, we  used the else if to indicate two different situations . That means if the situation of if is not met,  else if will be checked, or it will run the else part of the program. In  case of tan(x), if input is pi/2 then it will return infinity, for pi/4 it will return 1 and in other cases it will return the value according to the formula. Let's see once -
    totan@Home-Computer ~/bc $ bc custom_lib.bc -l
    bc 1.06.95
    Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
    This is free software with ABSOLUTELY NO WARRANTY.
    For details type `warranty'. 
    
    tan(pi/2)
    10000000000000000000000000000000000000000
    
    tan(0)
    0
    
    cot(0)
    10000000000000000000000000000000000000000
    
    cot(pi/2)
    0
    
    cot(pi/4
    (standard_in) 11: syntax error
    
    cot(pi/4)
    1
    
    tan(pi/4)
    1
    
    tan(pi/6)
    .5776313010034497200431518875171948073868
    
    tan(pi/10)
    .3250595004727384774258910058063649166791
    
    tan(pi/180)
    .0174620920098073892786660773694508440827
    
    sin(pi/180)
    .0174594303072945382761249742439511767753
    
    sin(pi/pi)
    .8414709848078965066525023216302989996225
    sin(radian(90))
    .9999998001333682524818408858972908885418
    
    cos(radian(90))
    -.0006322445915532736545183507752145567248
    
    tan(radian(90))
    -1581.6660411069837079729290816982181726254171


    You may have noticed the last few lines. Maybe many people have understood the reason why the discrepancy. Actually degree*((22/7)/180)is not exactly same as its radian equivalent, so tan function can not run the correct segment of program and returns incorrect output.
    Let's see how it can be fixed. Here we will take the help of another operator, which is called boolean or operator. If you do not know about boolean algebra, then I will embed a video here that will help you understand -

    This time we will see how we will use this boolean or operation in bc. For that I'll make a little change in the previous program -
    scale=40;
    pi=22/7;
    
    define degree(radian) { return radian * (180/(22/7)); }
    define radian(degree) { return degree * ((22/7)/180); } 
    
    define sin(x) { 
     if (x == pi/2 || x == radian(90)){
      return 1;
     } else {
      return s(x);
     }
    }
    define cos(x) {
     if (x == pi/2 || x == radian(90)){
                    return 0;
            } else {
      return c(x); 
     }
    }
    define tan(x) {
     if (x == pi/2 || x == radian(90)){
                    return 10^40;
     } else if (x == pi/4 || x == radian(45)){
                    return 1;
            } else {
      return sin(x)/cos(x); 
     }
    }
    define cot(x) { 
     if (x == 0){
                    return 10^40;
            } else if (x == pi/4 || x == radian(45)){
      return 1;
     } else {
      return cos(x)/sin(x); 
     }
    }
    define sec(x) { 
     if (x == pi/2 || x == radian(90)){
                    return 10^40;
            } else {
      return 1/cos(x); 
     }
    }
    define cosec(x) { 
     if (x == 0){
                    return 10^40;
            } else {
      return 1/sin(x); 
     }
    }
    
    define arctan(x) { return a(x); }
    define arcsin(x) { return 2*arctan(x/(1+sqrt(1-x^2))); }
    define arccos(x) { return pi/2 -  arcsin(x); }
    define arccot(x) { return pi/2 - arctan(x); }
    define arccsc(x) { return arcsin(1/x); }
    define arcsec(x) { return arccos(1/x); }

    With this input to this modified program we will calculate some values ​​again -
    totan@Home-Computer ~/bc $ bc -l custom_lib.bc 
    bc 1.06.95
    Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
    This is free software with ABSOLUTELY NO WARRANTY.
    For details type `warranty'. 
    
    sin(radian(90))
    1
    
    sin(pi/2)
    1
    
    cos(radian(90))
    0
    
    cos(pi/2)
    0
    
    cos(pi/4)
    .7068832136245869031428194525782683945745
    
    tan(pi/4)
    1
    
    tan(radian(45))
    1
    
    cot(radian(45))
    1
    
    sec(radian(90))
    10000000000000000000000000000000000000000
    
    cosec(0)
    10000000000000000000000000000000000000000
    
    cosec(90)
    1.1185724071637082998393926874013871636495
    
    cosec(radian(90))
    1.0000000000000000000000000000000000000000

    In this way you can do various types of calculations by programming and using different operators. In our next post we will see how we can calculate the factorial with the help of loop.