Csound Csound-dev Csound-tekno Search About

Errors in multiplication

Date2005-09-29 04:22
Fromdigger vermont
SubjectErrors in multiplication
Attachmentscond-02.csd  
Hello,
	I am once again going round in circles with

if ( it1 < 12)

I discovered my problem is that when performing a multiplication with
"it1" there are small errors introduced so I'm not getting the expected
results to the test, "( it1 < 12 )".

Some examples:

6.04 - 6.00             =       0.040000
(6.04 - 6.00)*100       =       3.999996

6.05 - 6.00             =       0.050000
(6.05 - 6.00)*10        =       0.500002
(6.05 - 6.00)*100       =       5.000019
(6.05 - 6.00)*1000      =       50.000191

It doesn't look like much but it sure plays havoc with a less than
statement. I've included a csd that show the error.
I'm using CS5 from CVS updated about a week ago.

I would guess this is a bug.  It looks like the bug tracking on
sourceforge isn't actively used. Where is the best place to file a bug?


Thanks
digger



Date2005-09-29 11:33
FromIstvan Varga
SubjectRe: Errors in multiplication
digger vermont wrote:

> I discovered my problem is that when performing a multiplication with
> "it1" there are small errors introduced so I'm not getting the expected
> results to the test, "( it1 < 12 )".
> 
> Some examples:
> 
> 6.04 - 6.00             =       0.040000
> (6.04 - 6.00)*100       =       3.999996
> 
> 6.05 - 6.00             =       0.050000
> (6.05 - 6.00)*10        =       0.500002
> (6.05 - 6.00)*100       =       5.000019
> (6.05 - 6.00)*1000      =       50.000191
> 
> It doesn't look like much but it sure plays havoc with a less than
> statement. I've included a csd that show the error.
> I'm using CS5 from CVS updated about a week ago.
> 
> I would guess this is a bug.  It looks like the bug tracking on
> sourceforge isn't actively used. Where is the best place to file a bug?

This is normal behavior of floating point hardware that represents
numbers in a binary format. In general, no floating point value
can be accurate that cannot be calculated by dividing an integer
(which must be <= 16777216 in the case of single precision) with
a power of two value.
The only calculations that are safe are adding, subtracting, or
multiplying not very large (see above why) integers.
To work around the problem, that is not really specific to Csound
at all, you may try replacing comparisons like shown below:

   (it1 < 12)       (it1 < 11.99999)
   (it1 <= 12)      (it1 < 12.00001)
   (it1 == 12)      (it1 > 11.99999 && it1 < 12.00001)
   (it1 >= 12)      (it1 > 11.99999)
   (it1 > 12)       (it1 > 12.00001)
   (it1 != 12)      (it1 < 11.99999 || it1 > 12.00001)

when comparing against 'n', you may expect the actual value in
the range 0.999999*n to 1.000001*n with single precision, but
this also depends on the complexity of operations performed.
Note again that as long as you only use small integers, and
simple operations that should produce an exact integer result
from integer operands (examples: +, -, *, &, |, #, ~), it
may be safe to assume accurate results.
Also, you can round a value to the nearest integer with round().