【发布时间】:2013-06-03 02:46:42
【问题描述】:
好吧,我知道什么是机器精度,但是这个,我看不懂……
代码:
console.log("meanX",meanX);
meanX2 = meanX * meanX; //squared
console.log("meanX2",meanX2);
控制台输出:
meanX 300.3
meanX2 28493.4400000000002
如果您想知道,meanX2 的正确值应该是 90180.09 这只是屏幕截图中可见的众多示例之一。
.toFixed(6) 似乎可以解决这个问题...但我不知道为什么没有它它就无法工作。
编辑
好的,我不想在这里发布整个程序代码,因为首先我不是唯一的作者,其次,我也不希望在未经我们许可的情况下复制此内容。但我很乐意解释我是如何得到这个错误的,并将在这里发布整个方法/功能代码。
正如您可能从窗口标题中猜到的那样,此代码属于车道检测算法。我们使用 Three.js/webgl 在视频的每一帧上运行一些预处理着色器,然后我们分析生成的图像。您在屏幕截图中看到的方法/功能是一种垂直线拟合算法,是整个事情的一部分。 我可以看到算法运行良好,因为我在视频顶部绘制了车道,并且放置得很好。直到突然车道变成了单杠。这种意外行为的发生正是由于我在此处描述的现象,因为从那一刻起,我开始在控制台中看到错误的数学运算。
另外,由于视频和算法每次运行的 fps 略有不同,问题并不总是在视频的同一时刻发生,有时根本不会发生。
这是代码(它有一些改动,因为我试图隔离问题):
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
};
};
现在,我试图了解造成这种情况的原因,最奇怪的是,当我放置这种形式的陈述时,似乎
var x = ... meanY * meanY ...;
在 meanX2 归因之前,问题发生了。否则不会。
另外,我试图在调试器中捕捉到这个异常,但是当我进入调试选项卡时,问题就消失了。并且值再次正确。
我当然不相信黑魔法,而且我知道您可能对此持怀疑态度。 我也会的。但这里有一个 video 的链接显示它正在发生: The video
编辑2:
我设法在另一台计算机上重现了这个问题。两者都有 ubuntu 和使用 firefox(版本 20 和 21)。
编辑3:
很抱歉花了这么多时间!这是一个包含该问题的 zip。只需在任何网络服务器中运行它。提到的代码在 LaneDetection.js 中。在文件中搜索“HERE”即可找到。
https://docs.google.com/file/d/0B7y9wWiGlcYnYlo1S2pBelR1cHM/edit?usp=sharing
问题可能不会在第一次尝试中发生。如果是这种情况,请刷新页面并重试。当线条变水平时,您就知道它就在那里。正如我所说,我在 ubuntu 上的 Firefox 版本 20 和 21 中看到了这个问题。在 chrome 中它从未发生过。
顺便说一句,我注意到在 firefox 中更改 javascript.options.typeinference 标志似乎可以解决问题...我不知道该标志的确切作用,但也许这种优化在 firefox 中没有正确实现?
【问题讨论】:
-
当我尝试这个时,我没有得到类似的结果。没有“浮点很奇怪”的问题会导致这种异常。在我尝试的任何浏览器中,计算都可以正常工作。
-
@Pointy 没错!我不明白人们。这不是关于一个小的浮点精度错误..!
-
@karthikr 当您看到小数点/位时,请先阅读问题,然后再做出假设
-
您的问题的功能演示怎么样?发生了一些你没有向我们展示的事情。
-
@joxnas - 我认为没有人怀疑这在您运行代码时实际上正在发生。但是,如果您自己实际上看不到它的实际效果,那么尝试对此类问题进行故障排除是非常困难的。这就是错误报告被关闭为“无法重现”的原因。你有很多人对此感到好奇,但我们没有任何方法可以真正提供帮助,除非我们能看到它的实际作用并戳它看看发生了什么。如果有任何方法可以制作一个重复问题的测试页面,我敢打赌有人可以马上解决。