12

High, I need to test my arbitrary precision calculator, and bc seems like a nice yardstick to compare to, however, bc does truncate the result of each multiplication to what seems to be the maximum scale of the involved operands each.

Is there a quick way to turn this off or to automatically set the scale of each multiplication to the sum of scales of the factors so that it doesn't lose any precision?

If you have a more elegant solution to this involving something other than bc, I would appreciate your sharing it.

Example:

$ bc <<< '1.5 * 1.5'
2.2

The real answer is 2.25.

1
13

You can control the scale that bc outputs with the scale=<#> argument.

$ echo "scale=10; 5.1234 * 5.5678" | bc
28.52606652

$ echo "scale=5; 5.1234 * 5.5678" | bc
28.52606

Using your example:

$ bc <<< 'scale=2; 1.5 * 1.5'
2.25

You can also use the -l switch (thanks to @manatwork) which will initialize the scale to 20 instead of the default of 0. For example:

$ bc -l <<< '1.5 * 1.5'
2.25

$ bc -l <<< '1.52 * 1.52'
2.3104

You can read more about scale in the bc man page.

4
  • 5
    Or shorter: bc -l. “ -l (The letter ell.) Define the math functions and initialize scale to 20, instead of the default zero” – bc specification – manatwork Jun 20 '13 at 8:33
  • @manatwork - thanks, didn't notice that switch. – slm Jun 20 '13 at 8:37
  • Thanks. I guess I could set the scale to 2147483647 (which happens to be equal to INT_MAX), which bc tells me is the maximum scale value I can set (I'm am goint that far in my tests), but I'll guess I'll only test it with integers and give bc the performance benefits that come from using dynamic-length numbers. – PSkocik Jun 20 '13 at 11:10
  • 1
    For bc multiplication, the scale of the result is exactly min(max(sx,sy,scale),sx+sy) where sx and sy are the scales of x and y in x*y. Setting scale=scale(x)+scale(y) will give the maximum precision needed. Setting scale to a higher number (like a 1000) will not increase the scale of the result. The scale variable only affect s directly the result of division scale=1000; a/1 will create a result with 1000 decimal digits (after the dot) no matter what the scale of a was before. – Isaac Aug 20 '18 at 22:20
1

Try this :

$ bc
scale=10
1.5 * 1.5
2.25

Search bc's man for scale variable

0

I've created this bash function which won't display trailing zeroes

calc () { MAX_PRECISION=20; bc <<< "scale=$MAX_PRECISION; scale = scale($@); $@"; }

Example: calc 1.25^3 = 1.953125

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.