gavinhoward / bc

An implementation of the POSIX bc calculator with GNU extensions and dc, moved away from GitHub. Finished, but well-maintained.
https://git.gavinhoward.com/gavin/bc
Other
145 stars 29 forks source link

bc freezes evaluating cbrt(0.01) #64

Closed ikolesnikes closed 1 year ago

ikolesnikes commented 1 year ago

bin/bc enters an infinite loop while evaluating the cube-root of 0.01

bin/bc -l -e 'cbrt(0.1)' returns .46415888336127788924 (which is expected)

bin/bc -l -e 'cbrt(0.01)' freezes

Looking at the definition of root(x,n) in lib2.bc the following loop never exits

while(r!=q){
    r=q
    q=(p*r+x/r^p)/n
}

A simple hack makes the cbrt function working.

while(abs(r-q)>0.000001){
    r=q
    q=(p*r+x/r^p)/n
}
gavinhoward commented 1 year ago

Yes, this is a bug. I have reproduced it.

Your fix pointed right to the problem, which I suspected: it ran into a pathological case where the two values, r and q, never equaled each other because they would keep switching, i.e., r would equal x, and q would equal y, then on the next iteration, r would equal y, and q would equal x.

This is the reason I hate algorithms that are calculated by series. They can easily have problems like this.

I tried to fix it with 01230fcd9cfb547c5666247e1a36c624d3f2d01c. It increases the precision, but then does the comparison at a smaller precision.

Can you pull and test it for me? I'll start my release process in the meantime.

ikolesnikes commented 1 year ago

I tested your solution and it worked! Maybe it's worth to add a test for this case.

Never mind, you already did it.

gavinhoward commented 1 year ago

Yes, but you are right that if I did not, I should have!

I will put out a release with the fix as soon as I can. I'll close this issue at that time.

gavinhoward commented 1 year ago

Release 6.5.0 is out! Thank you for the report!