Apparent bug with MathMod

 
There is an apparent bug with MathMod; the following code (copied from the documentation with the inputs changed) produces and output of 0.1

double x=0.6,y=0.1,z;
z=MathMod(x,y);
Alert("The remainder of ",x," / ",y," is ",z);

Can anyone shed some light on this (I have tried normalizing all the doubles to various significant digits to no avail)?
 
Interestingly enough x=0.2 produces the correct answer of 0
 
This is a known issue with operations with double values due to discretisation error.
 
The most reliable workaround is to use integers instead
double x=0.6,y=0.1,z;
z=MathMod(x,y);
Alert("The remainder of ",x," / ",y," is ",z);
 
double epsilon = 0.00000000001; // Must be small enough not to affect precision
double factor = 10000.; // Must be large enough not to loose precision
int ix, iy, iz;
 
ix = x * factor + epsilon;
iy = y * factor + epsilon;
iz = ix % iy;
 
z = iz / factor;
Alert("The real remainder of ",x," / ",y," is ",z);
 

That is effectively what I did; I just wanted to make certain I wasn't losing my mind.

Scott

Irtron:
The most reliable workaround is to use integers instead
double x=0.6,y=0.1,z;
z=MathMod(x,y);
Alert("The remainder of ",x," / ",y," is ",z);
 
double epsilon = 0.00000000001; // Must be small enough not to affect precision
double factor = 10000.; // Must be large enough not to loose precision
int ix, iy, iz;
 
ix = x * factor + epsilon;
iy = y * factor + epsilon;
iz = ix % iy;
 
z = iz / factor;
Alert("The real remainder of ",x," / ",y," is ",z);


 
I guess, I should add this here, from a previous topic:
sometimes double int simple conversions don't work either

"Zap 2006.10.29 20:33
int x;
double y = 1.00000000;

x = y;

This is a simplificated code from one of my scripts, that behaves strange. I found out why:
When I do this, x will be sometimes 0, sometimes 1. I couldn't figure out yet what does the result depend on.

If I use x = NormalizeDouble(y,4) * 10000, then it gives also contradicting results.

If I use
int x = StrToInteger(DoubleToStr(y,0));
everything works okay.

Shouldn't int x = double y be simple conversion?"

Try it:

int Ticks=0;
int loghandle;
double PrevBid;
double DiffDouble;
int DiffInt;

int deinit()
{
FileClose(loghandle);
return(0);
}

int start()
{
Ticks ++;
if (Ticks == 1)
{
loghandle = FileOpen("log.csv",FILE_CSV|FILE_READ|FILE_WRITE,';');
PrevBid = Bid;
}
else
{
DiffDouble = Bid/Point - PrevBid/Point;
DiffInt = DiffDouble;

FileWrite(loghandle, "DiffInt: "+DiffInt," DiffDouble: "+DiffDouble);

PrevBid = Bid;
}
return(0);
}
 
Zap:
I guess, I should add this here, from a previous topic:
sometimes double int simple conversions don't work either
That's what the epsilon fracture added for before the conversion in the workaround.
 
Irtron:
That's what the epsilon fracture added for before the conversion in the workaround.
Ohh, I see now.
Wow, this is good. A bit complicated, but really does the trick about both issues.
Reason: