-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
executable file
·1022 lines (974 loc) · 39.7 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>GNU Basic Calculator (bc) for Mathematicians | Mike Pierce</title>
<meta name="author" content="Mike Pierce">
<meta name="description" content="The GNU basic calculator (bc) is a free and open source command-line program that performs arbitrary-precision calculations. Professionally speaking, bc is the most elegant tool for mathematicians to attain the feeling of power that comes with wielding a computer to do arbitrarily precise computations.">
<link rel="shortcut icon" type="image/png" href="../assets/favicon.png">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.13.18/dist/katex.min.css" integrity="sha384-zTROYFVGOfTw7JV7KUu8udsvW2fx4lWOsCEDqhBreBwlHI4ioVRtmIvEThzJHGET" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" media="all" href="../assets/main.css">
<link rel="alternate" href="../feed.xml" type="application/atom+xml" title="Mike Pierce's Feed">
<link rel="stylesheet" href="../assets/highlight.min.css">
<style media="print">
@page {size:letter; margin:0.75in 0.4in 0.75in 0.4in;}
h1 {font-size:30pt;}
h2 {font-size:18pt;}
h3 {font-size:12pt;}
body {font-size:9pt; line-height:calc(11em/9);}
main {column-count:2; column-gap:0.2in; column-fill:auto;}
figure {width:80%;}
</style>
<style>body{background-image:linear-gradient(transparent, var(--background)), url("banner.webp");}</style>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.13.18/dist/katex.min.js" integrity="sha384-GxNFqL3r9uRJQhR+47eDxuPoNE7yLftQM8LcxzgS4HT73tp970WS/wV5p8UzCOmb" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.13.18/dist/contrib/auto-render.min.js" integrity="sha384-vZTG03m+2yp6N6BNi5iM4rW4oIwk5DfcNdFfxkk9ZWpDriOkXX8voJBFrAO7MpVl" crossorigin="anonymous" onload="renderMathInElement(document.body);"></script>
<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.3.1/build/highlight.min.js" integrity="sha384-zDX/4RkDnpVxZkjJjxdzDsT1Kk2XThh7u47fXdgZ1W8AMjb//F4ZK4G4y7oNVHM1" crossorigin="anonymous"></script>
<script>hljs.highlightAll();</script>
</head>
<body>
<header>
<h1>The GNU Basic Calculator (bc): a Quick-Start Guide for Mathematicians</h1>
<ul>
<li> <a href="..">Mike Pierce</a></li>
<li> Tended 16 May 2024 </li>
<li class="screen"> <a href="GNU Basic Calculator (bc) for Mathematicians _ Mike Pierce.pdf">Print PDF</a></li>
<li class="screen"> Contribute: <a href="https://github.com/mikepierce/Article-GNU-bc-Guide">Fork on GitHub</a></li>
<li class="print"> Hosted at <a class="url "href="https://org.coloradomesa.edu/~mapierce2/bc">coloradomesa.edu/~mapierce2/bc</a></li>
</ul>
</header>
<main>
<section>
<p>
The <a href="https://en.wikipedia.org/wiki/Bc_(programming_language)" rel="external" title="Wikipedia: bc (programming language)">GNU basic calculator (bc)</a>
is a free and open source command-line program
that performs arbitrary-precision calculations
using the full capabilities of any computer.
This tool is more robust than most OS’s default calculator app,
much faster than a TI calculator,
and more convenient to use than the computational sledgehammers
Mathematica and Jupyter/python.
And it’s only “basic” by default;
bc is a full programming language too,
extendable with user-written functions.
</p>
<p>
Professionally speaking, bc is the most elegant tool
for mathematicians to attain
<a href="https://urbigenous.net/library/power.html" rel="external" title="a short story by Isaac Asimov">the feeling of power</a>
that comes with wielding a computer to do arbitrarily precise computations.
Pedagogically speaking, bc provides many benefits:
a means to subvert the pervasiveness of
<a href="https://gen.medium.com/big-calculator-how-texas-instruments-monopolized-math-class-67ee165045dc" rel="external" title="Big Calculator: How Texas Instruments Monopolized Math Class">proprietary hardware</a>
and software in classrooms,
an easy way to demonstrate the computational capabilities of a computer to students,
and also an accessible avenue for students to operate a computer as a calculator for themselves.
</p>
</section>
<section>
<nav>
<h2 id="contents"> Contents </h2>
<ul>
<li> <a href="#nix"> Installing on Linux/macOS</a></li>
<li> <a href="#windows"> Installing on MS Windows</a></li>
<li> <a href="#usage"> Getting Started Using bc</a>
<ul>
<li> <a href="#var"> Using Variables</a></li>
<li> <a href="#scale"> Controlling the Scale of bc’s Computations</a></li>
<li> <a href="#pow"> Handling Fractional Exponents</a></li>
<li> <a href="#int"> Getting the Integer Part of a Number</a></li>
<li> <a href="#mathlib"> Extending bc with its Math Library</a></li>
<li> <a href="#bases"> Computations in Different Bases</a></li>
</ul>
</li>
<li> <a href="#programming"> Programming: Functions, Arrays, & Limitations </a>
<ul>
<li> <a href="#functions"> Defining Functions </a></li>
<li> <a href="#print"> Printing Output & Reading Input </a></li>
<li> <a href="#control"> Control-Flow Syntax & Arithmetic </a></li>
<li> <a href="#arrays"> Array Variables & Loops </a></li>
<li> <a href="#limits"> Limitations of bc </a></li>
</ul>
</li>
<!-- <li> <a href="#readline"> GNU Readline Keyboard Shortcuts </a></li> -->
<li> <a href="#exercises"> Exercises & Challenges</a></li>
<li> <a href="#links"> Links & References</a></li>
<li> <a href="#aux"> My File of Auxiliary Functions</a></li>
<li> <a href="#fork"> Fork this Guide on GitHub</a></li>
</ul>
</nav>
</section>
<section>
<h2 id="nix"> Installing on Linux/macOS </h2>
<p>
On macOS and most Linux operating systems bc will already be installed.
If not, you can install it using your package manager.
For example on a Debian-based OS like Ubuntu
run <code>sudo apt install bc</code>.
Similarly on macOS you can install bc via
the <a href="https://brew.sh" rel="external">homebrew</a>
with <code>brew install bc</code>.
</p>
<p>
Running the command <code>bc</code> in your terminal
will display bc’s <em>copyright</em> banner and start bc interactively.
You can suppress this banner with the <code>-q</code> option,
and load bc’s math library with the <code>-l</code> option.
It’s also helpful to keep a running collection
of functions you write in a file, say <em>functions.bc</em>,
which you load into bc on startup.
All of this can be done automatically when you start bc
by setting the environment variable <code>BC_ENV_ARGS</code>,
by including this line in your shell’s (bash, zsh, …) configuration file:
</p>
<pre>
<code class="language-bash">export BC_ENV_ARGS="-lq /PATH/TO/functions.bc"</code>
</pre>
</section>
<section>
<h2 id="windows"> Installing on MS Windows </h2>
<p>
Although bc was originally written for unix-based operating systems,
it’s been
<a href="http://gnuwin32.sourceforge.net/packages/bc.htm" rel="external" title="Bc for Windows via GnuWin">ported to windows via GnuWin</a>.
If you have administrative privileges on your Windows machine
just download the Setup files to install bc.
If not — like if you’re using a classroom computer
locked down by your school’s IT department — you can
“portably” install bc.
Download the <a href="http://gnuwin32.sourceforge.net/downlinks/bc-bin-zip.php" rel="external">Binaries</a>
and the <a href="http://gnuwin32.sourceforge.net/downlinks/bc-dep-zip.php" rel="external">Dependencies</a>
zip archives from the GnuWin page.
Extract those zip archives, and move the files somewhere convenient.
Copy the file <em>readline5.dll</em> from the dependencies archive
into the same directory as <em>bc.exe</em>.
You’ll want to keep an auxiliary file of functions you write,
<em>functions.bc</em>, in this same directory.
</p>
<figure>
<div>
<img width=648 src="img/files.webp" alt="Screenshot: a directory containing the specified files in Windows" title="This is what my folder containing bc looks like">
<figcaption>
Screenshot: a directory containing the specified files in Windows
</figcaption>
</div>
</figure>
<p>
To suppress bc’s <em>copyright</em> banner,
and automatically load the <a href="#mathlib">math library</a>
and your auxiliary functions when you start bc,
create a shortcut to <em>bc.exe</em> that includes the arguments
<code>-lq functions.bc</code> to bc in the <em>Target</em> of the shortcut file.
You could name the shortcut file something like <em>bcmath</em>
and start it quickly by searching “bcmath” under the Windows Start menu.
</p>
<figure>
<div>
<img width=432 src="img/shortcut.webp" alt="Screenshot: how to edit the Target field in Windows" title="This is what my shortcut target field looks like" >
<figcaption>
Screenshot: how to edit the <em>Target</em> field in Windows
</figcaption>
</div>
</figure>
</section>
<section>
<h2 id="usage"> Getting Started Using bc</h2>
<p>
The <a href="https://www.gnu.org/software/bc/manual/html_mono/bc.html" rel="external">bc manual</a>
comprehensively describes its usage and features,
so this quick-start guide will be a simple distillation
of the key ideas and quirks of using bc,
and a few miscellaneous tips.
</p>
<p>
Since bc is a command-line calculator,
no longer will you waste time commuting your hand between your mouse and keyboard.
Running bc, simply type in an expression, press <kbd>Enter</kbd> to evaluate it,
and the result will be printed on the next line.
To stop any currently running computation (because it’s taking longer than expected)
press <kbd>Ctrl</kbd>+<kbd>C</kbd>.
To quit and exit bc,
either type the command <code>quit</code>
or press <kbd>Ctrl</kbd>+<kbd>D</kbd>.
</p>
<p>
Input preceded by a <code>#</code> character is ignored by bc,
which is intended to be used to leave comments in code.
</p>
<pre>
<code class="language-python"># Adding Three and Four
3 + 4</code>
<samp>7</samp>
</pre>
<h3 id="var">Using Variables</h3>
<p>
You can assign values to variables using <code>=</code>,
which is helpful for longer computations.
</p>
<pre>
<code class="language-python">a = 13846000729558555774154292420
b = 63050430913919525940448
hypotenuse_squared = a^2 + b^2
sqrt(hypotenuse_squared)</code>
<samp>13846000729702111914156643652.00000000000000000000</samp>
</pre>
<p>
Variables don’t have to be initialized like they do in most programming languages.
GNU bc will just infer the data type of your variable:
either a number or an <a href="#arrays">array of numbers</a>.
Variable names must start with a lowercase letter,
but otherwise can be any combination
of lowercase alphanumerical characters and underscores.
So using <code>h2</code> instead of <code>hypotenuse_squared</code> above
would’ve been just fine.
<strong>Caution</strong>: Capital letters are reserved
for expressing numbers in bases higher than ten.
</p>
<p>
The special variable <code>last</code>
contains the output of the previous command,
allowing you to quickly feed calculation results into new calculations.
Alternatively, a single period character <code>.</code> is a shorthand
for <code>last</code>.
</p>
<pre><code class="language-python">a = 13846000729558555774154292420
b = 63050430913919525940448
a^2 + b^2</code>
<samp>191711736206911415591997907991571150760667877089711897104</samp>
<code class="language-python">sqrt(.)</code>
<samp>13846000729702111914156643652.00000000000000000000</samp>
</pre>
<h3 id="#scale"> Controlling the Scale of bc’s Computations</h3>
<p>
The special variable <code>scale</code>
gives you control over the fractional precision of bc’s output,
setting the number of digits
to the right of the <a href="https://en.wikipedia.org/wiki/Decimal_separator#Radix_point" rel="external" title="Wikipedia: Radix Point">radix point</a>
(decimal point in base ten)
that bc will store during computations.
This simple control over the precision of calculations
is the shining feature of bc.
Loading the <a href="#mathlib">math library</a>
sets <code>scale</code> to 20,
but you can manually change this to whatever suits your needs:
</p>
<pre>
<code class="language-python">sqrt(2)</code>
<samp>1.41421356237309504880</samp>
<code class="language-python">scale = 42
sqrt(2)</code>
<samp>1.414213562373095048801688724209698078569671</samp>
</pre>
<p>
Conversely, there is a function <code>length()</code>
that returns the number of an input’s significant digits,
and a function <code>scale()</code>
that returns the number of significant digits to the right of the radix point.
</p>
<pre>
<code class="language-python">gelfond = 23.1406926
length(gelfond)</code>
<samp>9</samp>
<code>scale(gelfond)</code>
<samp>7</samp>
</pre>
<p>
<strong>Caution</strong>: the value of <code>scale</code> is <em>not</em>
the number of decimal places you may assume to be accurate.
Rounding error can accumulate:
</p>
<pre>
<code class="language-python">scale=2
9*(1/9)</code>
<samp>.99</samp>
</pre>
<p>
For a stark example, see how bc could lead us astray from the fact that
\(\lim_{x \to 0} \frac{\ln(x+1)}{x} = 1\).
Setting <code> scale=5 </code> and
using <code>l()</code> as the natural log function:
</p>
<pre>
<code class="language-python">x=10^(-1); l(x+1)/x</code>
<samp>.95310</samp>
<code class="language-python">x=10^(-2); l(x+1)/x</code>
<samp>.99500</samp>
<code class="language-python">x=10^(-3); l(x+1)/x</code>
<samp>.99000</samp>
<code class="language-python">x=10^(-4); l(x+1)/x</code>
<samp>.90000</samp>
<code class="language-python">x=10^(-5); l(x+1)/x</code>
<samp>0</samp>
</pre>
<p>
All you can say is that the difference
between your calculated value and the “true value”
is less than \(10^{n-\text{scale}}\) for some \(n\),
depending on the algorithmic complexity of your calculation
and magnitude of your parameters.
Discovering exactly what \(n\) must be in a given case
requires one dive into the world of
<a href="https://en.wikipedia.org/wiki/Numerical_analysis" rel="external" title="Wikipedia: Numerical Analysis" >numerical analysis</a>.
</p>
<h3 id="pow">Handling Fractional Exponents</h3>
<p>
Simply doing arithmetic in bc, the first thing you’ll notice
is that bc can’t immediately handle non-whole numbers as exponents.
Trying to calculate \(2.71^{3.14}\) as a decimal number
with the command <code>2.71^3.14</code> will throw an error.
Instead you’ll need to use a custom function for this,
based on the functions <code>e(x)</code>\( = \mathrm{e}^x\)
and <code>l(x)</code>\( = \ln(x)\) from bc’s math library,
which do accept fractional parameters.
Here’s a <code>pow</code> function that evaluates \(b^x\)
for an arbitrary base <code>b</code> and exponent <code>x</code>.
</p>
<pre>
<code class="language-c">define pow (b,x) { return e(x*l(b)) }</code>
</pre>
<p>
Then you can compute \(2.71^{3.14}\) as <code>pow(2.71, 3.14)</code>.
That’s a good function to keep in your auxiliary <em>functions.bc</em> file.
Details about the <a href="#mathlib">math library</a>
and <a href="#programming">writing functions</a> can be found later in this guide.
</p>
<h3 id="int">Getting the Integer Part of a Number</h3>
<p>
The modus operandi of bc is to work at some fixed scale,
so it doesn’t store the integer part of a number for easy access.
You can calculate the integer part of a number
by temporarily changing the scale though.
</p>
<pre>
<code class="language-c">define int(x) {
auto s;
s=scale;
scale=0;
x/=1;
scale=s;
return x;
}</code>
</pre>
<p>
This is also a helpful function to keep in your auxiliary functions file.
</p>
<h3 id="mathlib"> Extending bc with its Math Library </h3>
<p>
Besides support for basic arithmetic operations
like addition, multiplication, integer exponentiation, etc,
the only mathematical function built into bc is <code>sqrt()</code>.
Loading bc’s math library with the <code>-l</code> option
defines the following additional functions:
</p>
<ul>
<li><code>s(x)</code>, the sine of \(x\), for \(x\) in radians.</li>
<li><code>c(x)</code>, the cosine of \(x\), for \(x\) in radians.</li>
<li><code>a(x)</code>, the arctangent of \(x\), arctangent returns radians.</li>
<li><code>l(x)</code>, the natural logarithm of \(x\).</li>
<li><code>e(x)</code>, the exponential function of raising \(\mathrm{e}\) to the value \(x\).</li>
<li><code>j(n,x)</code>, the bessel function of integer order \(n\) of \(x\).</li>
</ul>
<p>
Only the trigonometric functions sine, cosine, and arctangent are included
<a href="https://unix.stackexchange.com/q/652493/74616" rel="external" title="'Who decided the bc math library will define sine cosine and arctangent?' on Unix.SE">for historical reasons</a>,
but really that’s all you need:
all other trigonometric functions can be expressed in terms of these three.
Doing this is left to the reader as an exercise,
… or see
<a href="#aux">my implementations at the end of this guide</a>.
</p>
<p>
Since the trigonometric functions in this library
expect angles expressed in radian measure,
it is helpful to have \(\pi\) stored as a constant.
Define \(\pi\) as four times the arctangent of one,
<code>pi = 4*a(1)</code>.
You could keep this line in your auxiliary <em>functions.bc</em> file,
along with these functions to convert between degree and radian measure:
</p>
<pre>
<code class="language-c">define radtodeg (x) { return x*(45/a(1)) }</code>
<code class="language-c">define degtorad (x) { return x*(a(1)/45) }</code>
</pre>
<h3 id="bases">Computations in Different Bases</h3>
<p>
Another shining feature of GNU bc —
one most useful to programmers,
but would be remiss not to mention —
is its capability to do computations in
<a href="https://en.wikipedia.org/wiki/Positional_notation#Base_of_the_numeral_system" rel="external">bases</a> 2 through 36.
The twenty-six capital letters of the alphabet
are used to represent digits beyond 9 as input;
this is why it’s
<a href="https://unix.stackexchange.com/q/199615/74616" rel="external">forbidden to use capital characters in variable names</a>.
By default, user input and displayed output
are supposed by bc to be in base-ten (decimal).
You can tell bc to display output in different base
by changing the variable <code>obase</code>,
and you can tell bc to expect user input in a different base
by changing the variable <code>ibase</code>.
For example:
</p>
<pre>
<code class="language-c">obase = 17
8675309</code>
<samp> 06 01 14 13 06 05</samp>
<code class="language-c">obase = 2
8675309</code>
<samp>100001000101111111101101</samp>
<code class="language-c">obase = 10
ibase = 17
61ED65</code>
<samp>8675309</samp>
</pre>
<p>
<strong>Caution</strong>:
If you change the value of <code>ibase</code> <em>before</em>
changing the value of <code>obase</code>,
remember that the value you assign to <code>obase</code>
will be interpreted in the base
you assigned to <code>ibase</code>.
Maybe just get in the habit of changing <code>obase</code> first.
</p>
</section>
<section>
<h2 id="programming"> Programming: Functions, Arrays, & Limitations </h2>
<p>
A quick note: this guide is specific to <strong>GNU</strong> bc —
there are other implementations of bc with tighter standards and more/less features.
But GNU bc is the version you’d most likely encounter in the wild.
</p>
<p>
The syntax of bc is similar to the syntax
of the C programming language, but much looser.
If you have no programming experience you should read the
<a href="https://www.gnu.org/software/bc/manual/html_mono/bc.html#SEC15" rel="external"><em>Statements</em> section of the bc manual</a>
for a more thorough treatment.
Otherwise if you have some experience programming in C or in any other modern language,
this section will help you translate that experience over to bc.
</p>
<h3 id="functions"> Defining Functions </h3>
<p>
The syntax for declaring a function in bc is
</p>
<pre>
<code class="language-c">define NAME ( PARAMETERS ) {
auto AUTO_LIST
...
return OUTPUT
}</code>
</pre>
<p>
where <code>NAME</code> is the name of your function,
<code>PARAMETERS</code> is the list of inputs to your function,
<code>AUTO_LIST</code> is a list of local variables you define
only for use in this function,
and <code>OUTPUT</code> is the value the function returns.
In the body of the function
the curly braces <code>{}</code> group
multiple independent commands together, and either semicolons <code>;</code>
or newlines (or both) separate those independent commands.
For example, here’s a function that returns the \(n\)<sup>th</sup> Fibonacci number
using the classic
<a href="https://en.wikipedia.org/wiki/Recursion_(computer_science)" rel="external" title="Wikipedia: Recursion (computer science)">recursive</a> definition.
</p>
<pre>
<code class="language-c">define fibonacci (n) {
auto i
if (n==1 || n==2) {
return 1
}
return fibonacci(n-1) + fibonacci(n-2)
}</code>
</pre>
<h3 id="print"> Printing Output & Reading Input</h3>
<p>
Within a function it may be helpful to
print text to the screen besides just the return value,
or to read user input while the function is running.
For these needs we have respectively the <code>print</code> command
and <code>read()</code> function.
The <code>print</code> command takes a comma-separated list of things
and prints them to the terminal,
while the command <code>x = read()</code> will store
a number entered interactively by a user to the variable <code>x</code>.
For example:
</p>
<pre>
<code class="language-c">define fibonacci_ask () {
auto r
print "Which Fibonacci number would you like?\n"
r = read()
return fibonacci(r)
}</code>
</pre>
<p>
That <code>\n</code> character prints a newline
to the terminal; otherwise bc would prompt
for input on that same line it printed the question.
</p>
<h3 id="control"> Control-Flow Syntax & Arithmetic</h3>
<p>
All of the control-flow keywords
<code>if</code>, <code>else</code>, <code>for</code>, <code>while</code>,
<code>continue</code>, <code>break</code>, and <code>halt</code>
are supported in GNU bc.
Instead of the keywords “true” and “false”
bc uses the numbers <code>1</code> and <code>0</code> respectively.
To provide some illustrative examples of the use of these keywords:
suppose you need a quick test to tell if two integers
<code>a</code> and <code>b</code> such that \(2 \lt a \lt b \)
might be adjacent Fibonacci numbers:
</p>
<pre>
<code class="language-c">if (int(10*(b/a)) == 16) {
print "a and b may be adjacent Fibonacci numbers\n"
} else {
print "a and b aren't adjacent Fibonacci numbers\n"
}</code>
</pre>
<p>
Or suppose you want to nicely display the first 42
Fibonacci numbers along with their index:
</p>
<pre>
<code class="language-c">for (i=1; i<=42; ++i) {
print i, " | ", fibonacci(i), "\n"
}</code>
</pre>
<p>
Or suppose you want the smallest power of 2
that has a leading digit of 7:
</p>
<pre>
<code class="language-c">x = 1
while(1) {
if (int(x/10^(length(x)-1)) == 7) {
break
}
x*=2
}
print x</code>
</pre>
<p>
With the exception of C’s bitwise operations
and two other special cases, bc shares all of C’s
<a href="https://www.gnu.org/software/bc/manual/html_mono/bc.html#SEC10" rel="external">arithmetic, assignment, comparison, and logical operators</a>.
Those two special cases are these:
</p>
<ul>
<li>
The caret <code>^</code> is an <em>integer</em> exponential operator,
not a bitwise operator. The command <code>a ^= b</code>
does the same thing as <code>a = a^b</code>.
</li>
<li>
The modulus operator <code>%</code> behaves the same in bc as in C
only when scale is set to zero.
Functionally <code>a % b</code> returns <code>a-(a/b)*b</code>
regardless of the value of <code>scale</code>.
In the language of the remainder theorem,
you can think of this general modulus operator this way:
for a fixed scale \(n\),
<code>a % b</code> returns the unique non-negative number \(r\)
less than \(b\times 10^{-n}\) for which there exists a number \(q\)
such that \(q \times 10^n\) is an integer and
\(a = q \times b + r\,.\)
For example, <code>scale=3; 8%7</code> returns <code>0.006</code>
since \(8 = 1.142\times7 + 0.006\,.\)
</li>
</ul>
<h3 id="arrays">Array Variables & Loops </h3>
<p>
In addition to simple variables, bc supports array variables,
iterable collection of variables indexed by non-negative integers
(indexing starts at zero).
The index of an array you’d like to access
is indicated by enclosing it in square brackets
<code>[</code><code>]</code> after the array’s name.
That is, the variable \(a_i\) for some \(i\in \mathbf{Z}^+\) is denoted as
<code>a[i]</code> in bc.
</p>
<pre>
<code class="language-python">a[1] = 13846000729558555774154292420
a[2] = 63050430913919525940448
h2 = a[1]^2 + a[2]^2
sqrt(h2)</code>
<samp>13846000729702111914156643652.00000000000000000000<samp>
</pre>
<p>
Simple variables and array variables of the same name
can co-exist with no conflict:
letting <code>a = a[1]^2 + a[2]^2</code> in that last example
would have been just fine.
Like simple variables, arrays don’t have to be initialized,
and the size of an array never needs to be declared.
The maximum size of an array in bc is
set as <code>BC_DIM_MAX</code>,
<a href="https://unix.stackexchange.com/q/704891/74616" rel="external">a value chosen at compile time</a>.
In my current version of bc, this value is \(2^{24}\,.\)
</p>
<p>
Arrays are useful for looping over some enumeration of data.
For example, we can write a more efficient <code>fibonacci()</code> function
by using a for-loop and storing previously computed Fibonacci numbers
in an array <code>fib</code>:
</p>
<pre>
<code class="language-c">define fibonacci (n) {
auto i, fib
fib[1] = fib[2] = 1
for (i=2; i<=n; ++i) {
fib[i] = fib[i-1] + fib[i-2]
}
return fib[n]
}</code>
</pre>
<h3 id="limits">Limitation of bc </h3>
<p>
There are a couple limitations of bc you should keep in mind
when considering if you’d like to use a more robust programming language.
</p>
<p>
In bc you cannot pass functions as parameters to other functions.
The only variable types —
and so the only entities that may be a function’s parameters —
are simple variables and arrays.
This limitation makes for messy code,
where any function that morally <em>should</em> have a function
as a parameter instead has to assume a globally-defined function
of a fixed name already exists.
I’ve been using the convention that such a function must be
globally defined and named <code>f</code>,
and its derivative named <code>ff</code>.
</p>
<p>
You cannot explicitly define the contents of an entire array at once.
I.e. the syntax <code>array = {8, 6, 7}</code> is not accepted,
and instead you’d have to use:
</p>
<pre>
<code class="language-python">array[0] = 8; array[1] = 6; array[2] = 7;</code>
</pre>
<p>
Similarly, since bc doesn’t keep track of the size of an array,
there is no command to print the entire contents of an array.
Instead you must keep track of the size of an array yourself
and loop over the indices to individually print the entries.
This makes working with data in bc cumbersome,
and doing any sort of statistics impossible.
</p>
<p>
On a related note, you can’t return an array from a function.
Instead you have to pass your array by reference as a parameter,
a feature of GNU bc not documented in the manual.
The syntax is demonstrated in this example:
</p>
<pre>
<code class="language-c">define fibonacci_next (*array[], n) {
array[n] = array[n-1] + array[n-2]
return array[n]
}</code>
</pre>
<pre>
<code class="language-python">fib[42] = 267914296
fib[43] = 433494437
fibonacci_next(fib[], 44)</code>
<samp>701408733</samp>
<code class="language-python">fib[42] = 267914296
fib[44]</code>
<samp>701408733</samp>
</pre>
<p>
Additionally there is no built-in support for matrices
(arrays-of-arrays).
</p>
</section>
<!--
<section>
<h3 id="readline">GNU Readline Keyboard Shortcuts</h3>
Using bc interactively,
there are a few keyboard shortcuts provided by
<a href="https://en.wikipedia.org/wiki/GNU_Readline#Emacs_keyboard_shortcuts">GNU readline</a>
to make navigating long commands easier.
Here some of the more helpful ones.
</p>
<ul>
<li>
<h4><kbd>Ctrl</kbd>+<kbd>a</kbd> </h4>
Move the cursor to the st<strong>a</strong>rt of the line; like <kbd>Home</kbd>
</li>
<li>
<h4><kbd>Ctrl</kbd>+<kbd>e</kbd> </h4>
Move the cursor to the <strong>e</strong>nd of the line; like <kbd>End</kbd>
</li>
<li>
<h4><kbd>Alt</kbd>+<kbd>b</kbd> </h4>
Move the cursor <strong>b</strong>ack one word
</li>
<li>
<h4><kbd>Alt</kbd>+<kbd>f</kbd> </h4>
Move the cursor <strong>f</strong>orward one word
</li>
<li>
<h4><kbd>Ctrl</kbd>+<kbd>t</kbd> </h4>
<strong>T</strong>ranspose the current and previous character
</li>
<li>
<h4><kbd>Ctrl</kbd>+<kbd>p</kbd> or <kbd>↑</kbd> </h4>
Access the <strong>p</strong>revious entry in the command history
</li>
<li>
<h4><kbd>Ctrl</kbd>+<kbd>n</kbd> or <kbd>↓</kbd> </h4>
Access the <strong>n</strong>ext entry in the command history
</li>
<li>
<h4><kbd>Ctrl</kbd>+<kbd>l</kbd> </h4>
C<strong>l</strong>ear the screen
</li>
</ul>
</section>
-->
<section>
<h2 id="exercises"> Exercises & Challenges</h2>
<p>
The best way to learn a new tool is on the job;
start using bc instead of whatever basic calculator you’ve been using,
and if you teach be sure to install it on your classroom computer
to have at hand during a lesson.
In case you need some initial inspiration to dive into bc,
here are some tasks you can complete as practice.
</p>
<p>
I’ve written functions to complete some of these tasks
in my own <em>functions.bc</em> file,
<a href="https://github.com/mikepierce/GNU-bc-Functions" rel="external">which you can find on GitHub</a>,
in case you’d like to compare solutions.
</p>
<ol>
<li>
<h4>The Quadratic Formula</h4>
<p>
Write a function that takes the coefficients
of a quadratic polynomial \(ax^2 + bx + c\) as input
and prints the roots of that polynomial.
Since there are two “outputs” of this function
you’ll likely want to <code>print</code> one of the roots
and return the other.
</p>
<p>
Alternatively, using bc version ≥1.07.1 you could print both roots
and have your function return nothing
using the <code>void</code> keyword:
</p>
<pre>
<code class="language-c">define void f (a,b,c) { ... }</code>
</pre>
<p>
For more of a challenge,
try to (efficiently) write the function
to compute the roots of a cubic or a quartic polynomial.
</p>
</li>
<li>
<h4>Decimal Digit as an Array</h4>
<p>
Given a decimal number \(x\)
create an array and write a loop that will
store the first \(n\) digits to the right of
the decimal point in \(x\) in the indices in the array.
</p>
<p>
More generally, write a function that takes
a decimal number \(x\) as input
and for some \(n \lt \)<code>scale</code> returns the \(n\)<sup>th</sup>
digit to the right of the decimal place in \(x\,.\)
</p>
</li>
<li>
<h4>Prime Factorization</h4>
Write a function that prints
the prime factorization of its input.
</li>
<li>
<h4>Newton’s Method</h4>
<p>
For a differentiable function <code>f</code>=\(f\)
and its derivative <code>ff</code>=\(f'\)
implement <a href="https://en.wikipedia.org/wiki/Newton's_method"rel="external" title="Wikipedia: Newton's Method" >Newton’s method</a>
of approximating a root of \(f\).
</p>
<p>
Then use this function to compute
the <a href="https://en.wikipedia.org/wiki/Dottie_number" rel="external" title="Wikipedia: Dottie Number">Dottie number</a>,
the constant defined to be the single real solution
to the equation \(\cos(x) = x\,,\)
accurate to 42 decimal places.
</p>
</li>
<li>
<h4>Numerical Integration</h4>
<p>
Write a function that, given a globally defined function <code>f</code>,
approximates the value of the definite integral
\[
\int\limits_a^b f(x)\,\mathrm{d}x\,.
\]
Can you write this function
to accurately compute the value of the integral up to <code>scale</code>?
</p>
</li>
</ol>
</section>
<section>
<h2 id="links"> Links & References </h2>
<p>
See the <a href="https://www.gnu.org/software/bc/manual/html_mono/bc.html" rel="external">GNU bc manual</a>
to learn <em>all</em> of bc’s functionality.
If you have a question and you can’t find the answer in the manual,
you can ask general questions about bc on the
<a href="https://unix.stackexchange.com/questions/tagged/bc?sort=newest" rel="external">Unix & Linux Stack Exchange</a>,
or programming-related questions about bc on
<a href="https://stackoverflow.com/questions/tagged/bc" rel="external">Stack Overflow</a>.
</p>
<p>
The maintainer of <code>phodd.net</code>
has authored a huge <a href="http://phodd.net/gnu-bc/" rel="external">library of bc functions</a>
and written a helpful <a href="http://phodd.net/gnu-bc/bcfaq.html" rel="external">bc FAQ page</a>.
Additionally, Keith Matthews has
written <a href="http://www.numbertheory.org/gnubc/gnubc.html" rel="external">some number theory programs for bc</a>.
So if you need a specific algorithm you don’t want to implement yourself,
these are the first places you should check.
</p>
<p>
And if you’re ever on Twitter having an argument
that could be settled with a computation, there is
<a href="https://twitter.com/bc_l" rel="external">a Twitter bot @bc_l that will execute bc code</a>.
</p>
</section>
<section>
<h2 id="aux"> My File of Auxiliary Functions </h2>
<p>
In case you’re not excited by the romantic notion
of implementing mathematical functions yourself as you need them,
here are two options:
copy any of the “basic” functions below into your own
<em>functions.bc</em> auxiliary file
to give you a more usable base to start using bc from,
or feel free to fork/clone my personal working collection
of bc functions from GitHub:
</p>
<nav>
<ul>
<li><a class="url" href="https://github.com/mikepierce/GNU-bc-Functions" rel="external">github.com/mikepierce/GNU-bc-Functions</a></li>
</ul>
</nav>
<h3>Helpful Constants & Functions</h3>
<pre>
<code class="language-python">pi=4*a(1)
ex=e(1)
define abs(x) { if (x>0) return x; return -x }
define sgn(x) { if (x>0) return 1; return -1 }
# Return the integer-part of a number (not the floor)
define int(x) {
auto s; s=scale; scale=0; x/=1; scale=s; return x;
}</code>
</pre>
<h3>Logarithms & Exponentials</h3>
<pre>
<code class="language-python">define log(x) { return l(x) }
define exp(x) { return e(x) }
define logb(x,b) { return l(x)/l(b) }
define pow(x,n) { return e(n*l(x)) }</code>
</pre>
<h3>Trigonometry</h3>
<pre>
<code class="language-python">define radtodeg(x) { return x*(45/a(1)) }
define degtorad(x) { return x*(a(1)/45) }
define cos(x) { return c(x) }
define sin(x) { return s(x) }
define tan(x) { return s(x)/c(x) }
define sec(x) { return 1/c(x) }
define csc(x) { return 1/s(x) }
define cot(x) { return c(x)/s(x) }
define arccos(x) {
if(x == 1) return 0
if(x == -1) return pi
return pi/2-a(x/sqrt(1-(x^2)))
}
define arcsin(x) {
if(x == 1) return pi/2
if(x == -1) return -pi/2
return sgn(x)*a(sqrt((1/(1-(x^2)))-1))
}
define arctan(x) { return a(x) }
define arcsec(x) { return arccos(1/x) }
define arccsc(x) { return arcsin(1/x) }
define arccot(x) { return pi/2-a(x) }</code>
</pre>
<h3>Combinatorics</h3>
<p>
Note these functions don’t bother to check
that their parameters are integers.
</p>
<pre>
<code class="language-python">define factorial(n) {
if (n<1)
return 1
return n*factorial(n-1)
}
# nCk, the number of ways to choose k of n objects
define choose(n,k) {
auto c
c = factorial(n)/(factorial(n-k)*factorial(k))
return int(c)
}
# nPk, the number of ways to permute k of n objects
define pick(n,k) {
auto i, r
r = n-k
for (i=1; n > r; --n)
i*=n
return i
}</code>
</pre>
</section>
<section>
<h2 id="fork"> Fork this Guide on GitHub </h2>
<p>
In keeping with the
<a href="https://maggieappleton.com/garden-history" rel="external" title="Maggie Appleton: A Brief History & Ethos of the Digital Garden">ethos of digital gardening</a>,
and of the internet being a living, community-tended library of humanity’s collective knowledge,
I don’t want this page to become a corpse of my sole authorship
cluttering the stacks of our library.
What a tragic misuse of the internet that would be.
No, I’d rather simply be the … maintainer? custodian? groundskeeper? … of this living guide.
Please feel free to become a co-author and tend to this page with me.
</p>
<h4>CONTRIBUTING</h4>
<p>
The <a rel="external" href="https://web.dev/learn/html/semantic-html">semantic HTML</a> for this page is
<a rel="external" href="https://github.com/mikepierce/Article-GNU-bc-Guide">hosted on GitHub</a>,
licensed as <a href="http://creativecommons.org/licenses/by-nc-sa/4.0/?ref=chooser-v1">CC BY-NC-SA 4.0</a>.
If you’d like to suggest an edit or addition to my instance of this guide,
<a rel="external" href="https://github.com/mikepierce/Article-GNU-bc-Guide/issues">create an issue on GitHub</a>,
fork the repository, make your changes, and submit a pull request.