[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: To round to the correct nearest number in a Linux basic calculator
From: |
Greg Wooledge |
Subject: |
Re: To round to the correct nearest number in a Linux basic calculator |
Date: |
Sat, 25 Sep 2021 19:24:00 -0400 |
On Sat, Sep 25, 2021 at 11:09:40PM +0000, Budi wrote:
> How do we round to the correct nearest number in a Linux basic calculator BC?
> It just round it down to precision digit number set on 'scale' variable
You don't. Don't. Do not do it. Do not attempt it. Seriously.
What you want to do instead: take the output from bc -l, with the full
precision that it gave you, and use printf to do the rounding.
unicorn:~$ x=$(bc -l <<< 1/19)
unicorn:~$ echo "$x"
.05263157894736842105
unicorn:~$ printf '%.7f\n' "$x"
0.0526316
Now, I know how you people are. You won't believe me. You never listen
to me. So, here is why you NEVER EVER EVER EVER EVER under any
circumstances run bc with a low "scale" as a substitute for rounding in
a second step.
Let's say you're calculating an exponential for a video game you're
playing. In this particular video game, there's a challenge that you
have to face which grows exponentially. You know which level you're
on, but you want to know exactly how strong the challenge is. So you
use the formula that the players discovered through research, which is
(level)^1.4
bc can't do that directly (it doesn't support fractional exponents), but
you remember enough mathematics to know how to rewrite this formula using
logarithms:
unicorn:~$ bc -l <<< 'e(1.4*l(500))'
6005.62216990715616614180
So the challenge strength at level 500 is about 6000. But we have all
that ugly noise after the whole number. So let's tell bc to use a
lower scale. It should work, right? Right?
unicorn:~$ bc -l <<< 'scale=3; e(1.4*l(500))'
5996.912
And it gets worse!
unicorn:~$ bc -l <<< 'scale=0; e(1.4*l(500))'
4447
It's not even CLOSE!
So, there you go. That's why you never run bc with a lower scale value.
The scale value doesn't determine the rounding of the final answer. It's
used to hold the intermediate values at *every* step along the way. The
more intermediate steps there are, the more wrong the answer becomes.