[Gnucash-changes] r13248 - gnucash/trunk/src/calculation - Fix Bug 107876 - financial calculator would call exit(1) if calculation resulted in an interest rate of zero.

Neil Williams linux at codehelp.co.uk
Mon Feb 13 04:26:52 EST 2006


On Monday 13 February 2006 2:08 am, Derek Atkins wrote:
> Quoting Neil Williams <codehelp at cvs.gnucash.org>:
> > _C (double eint, double pmt, unsigned beg)
> > {
> > -  return pmt * _B (eint, beg);
> > +  unsigned check = _B (eint, beg);

> I'm not convinced this patch is correct.  _B() returns a double,

I'm setting up an error state that is perpetuated through the code. If these 
are converted back to doubles, gnucash goes into an infinite loop. I'll do 
something about the data loss but we have to break the loop too.

I started looking at this just as you did - but eint == 0.0 must be treated as 
a special case or the whole thing gets v.ugly.

> but 
> you're assigning it to an unsigned -- so you're going to lose data
> in the case.  

Once you get to eint == 0.0 being true, the game is up, the code must simply 
shutdown ASAP. The code becomes unstable and far more serious data loss is 
inevitable. Data loss within the calculator at that point is largely 
irrelevant.

This is why exit(1) was being called originally - brute force error handling.
:-(

I've set a wrapper so that the data is preserved in the normal case but the 
error state itself does need to be an unsigned int.

> I also don't see why it matters here; there's nothing 
> illegal about multiplying by zero.

You'd have thought that, (I did), but reverting causes a permanent loop to be 
setup.

All these zero checks are nothing to do with the calculation, these are 
intended only as an error state and all code is to abort when this state is 
detected. There is no point worrying about data that may need to be 
calculated once eint is 0.0, it cannot be done. We just get out of the code 
as fast as we can.

> You're also inconsistent with your checks.  Sometimes you say:
>   if (foo)

The next line takes care of if (foo == 0.0) in the ? : ; conditional. We just 
don't want this line executing:
CC = (CC - fv) / (CC + pv);
if CC == 0.0
I know it should be OK because of the +pv but the code just keeps on looping. 
we can't risk _any_ calculation once eint == 0.0.

> > +  if(CC == 0) return 0.0;
>
> And yet another inconsistency --  == 0 instead of == 0.0.

Sorry about that, got carried away with the int error state. Fixed.

> Are you sure this code even still works?  Is there a test case that shows
> the actual bug(s)?

Yes and yes, in the bug report.
http://bugzilla.gnome.org/show_bug.cgi?id=107876

Enter any set of figures that would result from a zero-interest loan.

e.g. Clear interest rate, clear future value and payment amount. Set payment 
amount to a simple denominator of the loan amount (500) and future value to 
zero. Click calculate.

Gnucash would simply shutdown with exit(1) - offering no chance to save the 
current data file - hence the original bug. Now the calculator aborts and 
displays an interest rate of '-' and gnucash keeps running. It's almost 
intuitive, as errors go.
;-)

-- 

Neil Williams
=============
http://www.data-freedom.org/
http://www.nosoftwarepatents.com/
http://www.linux.codehelp.co.uk/

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://lists.gnucash.org/pipermail/gnucash-devel/attachments/20060213/42330843/attachment.bin


More information about the gnucash-devel mailing list