Allright, I know what machine precision is, but this, I can't understand...
Code:
console.log("meanX",meanX);
meanX2 = meanX * meanX; //squared
console.log("meanX2",meanX2);
Console output:
meanX 300.3
meanX2 28493.4400000000002
In case you are wondering, the correct value for meanX2 would be 90180.09 And this is only one of the many examples visible in the screenshot..
.toFixed(6) seems to fix this... But I have no idea why it doesn't work without it.
Edit
Ok, I don't want to post the whole program code here because in first place I'm not the only author, and second, I also wouldn't like this to be copied without our permission. But I'll gladly explain how I get this error and will post the whole method/function code here.
This code belongs, as you may have guessed from the window title, to a lane detection algorithm. We use Three.js/webgl to run some pre processing shaders on each frame of a video and then we analyze the resulting image. The method/function you see on the screenshot is a perpendicular line fitting algorithm and is part of the whole thing. I can see the algorithm running nicely because I have the lane being drawn on top of the video, and It is well placed. Until suddenly the lane turns into an horizontal bar. This unexpected behavior happens exactly because of the phenomenon I described here, since it's from that moment that I start to see wrong math in the console.
Also, because the video and algorithm run at slightly different fps everytime, the problem doesn't always happen in the same moment of the video, and sometimes It doesn't happen at all.
Here is the code (it has some alterations because I was trying to isolate the issue):
this.perpendicularLineFit = function (points, slopeSign) {
var count = points.length;
var sumX = 0,
sumY = 0;
var sumX2 = 0,
sumY2 = 0,
sumXY = 0;
var meanX, meanY;
var i, lowp = {}, highp = {};
var B;
var slope;
var originY;
for (i = 0; i < count; i++) {
sumX += points[i].x;
sumY += points[i].y;
sumX2 += points[i].x * points[i].x;
sumY2 += points[i].y * points[i].y;
sumXY += points[i].y * points[i].x;
}
meanX = sumX / count;
meanY = sumY / count;
//If you uncoment this, problem reappears:
//var numeratorLeft = meanY * meanY;
console.log("meanX",meanX);
var meanX2 = meanX*meanX;
console.log("meanX2",meanX2);
var numerator = (sumY2 - count * (meanY * meanY)) - (sumX2 - count * meanX2);
var denominator = (count * meanX * meanY - sumXY);
B = 0.5 * (numerator / denominator);
slope = -B + slopeSign * Math.sqrt(B * B + 1);
originY = meanY - slope * meanX;
slope = isNaN(slope) ? slopeSign : slope;
originY = isNaN(originY) ? originY : originY;
lowp.y = this.lowY;
lowp.x = (this.lowY - originY) / slope;
highp.y = this.highY;
highp.x = (this.highY - originY) / slope;
return {
low: lowp,
high: highp
};
};
Now, I was trying to understand what was causing this, and the most bizarre thing is that it seems that when I place a statement of this form
var x = ... meanY * meanY ...;
before the meanX2 attribution, the issue happens. Otherwise it doesn't.
Also, I tried to catch this anomaly in the debugger but just when I enter the debugging tab, the problem disapears. And the values turn correct again.
I certainly don't believe in black magic, and I know that you are probably skeptic to this. I would be too. But here is a link to a video showing it happening: The video
Edit2:
I managed to reproduce this issue in another computer.. Both having ubuntu and using firefox (versions 20 and 21).
Edit3:
I'm sorry it took so much time! Here is a zip containing the issue. Just run it in any webserver. The code mentioned is in LaneDetection.js. Search for "HERE" in the file to find it.
https://docs.google.com/file/d/0B7y9wWiGlcYnYlo1S2pBelR1cHM/edit?usp=sharing
The problem might not happen in the first attempts. If that's the case refresh the page and try again. When the lines get horizontal you know it's there. As I said, I saw this problem happening in firefox versions 20 and 21 on ubuntu. In chrome it never happened.
By the way, I noticed that changing javascript.options.typeinference flag in firefox seems to stop the problem... I don't know exactly what that flag does, but maybe this optimization is not correctly implemented in firefox?