There must be a few people out there who still use bc as a desk calculator. bc is a simple application that comes as standard on most unix and linux systems. It’s nicer to use than a graphical calculator app: less fussy, no mouse needed and you can see what you have typed.
bc Gets it Wrong
A recent mix-up with financial calculations lead me to discover that – unbelievably – bc was getting its sums wrong. This post explains the problem.
Normal bc Behaviour
What is £50 plus 17.5% ? bc tells us:
bash-4.2$ bc -q 50*1.175 58.750
The answer is £58.75. No problem there. How about 22/7 ?
bash-4.2$ bc -q 22/7 3
Ah, yes. When dividing, bc truncates everything after the decimal point from its answers. You have to set the “scale” to whatever number of decimal places you want, something which will be familiar to all users of bc:
bash-4.2$ bc -q 22/7 3 scale=2 22/7 3.14 scale=10 22/7 3.1428571428
That’s better.
Truncation Errors
So far so good. However, bc doesn’t just truncate answers, it also truncates internal values, and that is a bit naughty. For example, what is 1234 x (5/6) ? My pocket calculator says 1028.333333. So I would expect bc, with a scale setting of 2, to give the answer as 1028.33. But no:
bash-4.2$ bc -q scale=2 1234*(5/6) 1024.22
1024.22 ? That is wrong by more than 4 whole units. Or 0.4%. It gets worse with bigger numbers. Eg. 12345 x (6/7) = 10581.42857 according to my pocket Casio. But bc, with scale set to 2, will claim an answer of 10493.25, rather than what you would expect, ie. 10581.42. The error is now over 88 units, or about 0.8%.
This sort of thing could get you into trouble with the Inland Revenue.
Explanation
When you type “1234*(5/6)” into bc, it works out 5/6 first, stores that, then multiplies it by 1234 to give an answer of 1024.22. The answer is wrong because bc truncates the stored value for “5/6”, rather than doing the whole sum and just truncating the answer. In other words, it is doing something like this:
bash-4.2$ bc -q scale=2 5/6 .83 1234*.83 1024.22
I would call this a bug, or at least a misleading feature which not really explained in the man page. It is the use of parenthesis which can introduce this subtle error. Okay, this post should really be entitled “bc Truncation Errors” not “bc Rounding Errors”, strictly speaking.
Conclusion
bc is great and I will continue to use it. But take care with parenthesis, and if you need to use them, set the “scale” to something much larger that you really need. Or just use bc -l, which will automatically set the scale to 20. Or dust off your slide rule.