Python vs Javascript浮点算法给出了非常不同的答案。我究竟做错了什么?

时间:2011-08-07 17:56:15

标签: javascript python floating-point

Python version | Javascript version | Whitepaper

所以,我正在一个网站上计算两个玩家游戏的Glicko评级。它涉及很多浮点运算(平方根,指数,除法,所有令人讨厌的东西),我出于某种原因得到了一个完全不同的答案,从我逐行逐行翻译的算法的Python实现。 Python版本基本上给出了描述算法的原始白皮书中的示例的预期答案,但Javascript版本相当有点。

我是否在翻译中出错或Javascript的浮点数学不太准确?

Expected answer: [1464, 151.4]
Python answer: [1462, 155.5]
Javascript answer: [1470.8, 89.7]

所以评级计算不是那么糟糕,准确度为99.6%,但方差偏差为2/3!

编辑:人们已经指出Pyglicko版本中RD的默认值是200.这是原始实现者离开测试代码的情况,我相信,因为测试用例是在RD的人身上完成的。 200,但显然默认应该是350.但是,我在Javascript的测试用例中指定了200,所以这不是问题。

编辑:更改算法以使用map / reduce。评级不太准确,方差更准确,两者都没有明显的原因。 Wallbanging开始了。

2 个答案:

答案 0 :(得分:7)

通常你会得到这样的错误,你可以减去两个相似的数字 - 那么值之间通常无关紧要的差异就会被放大。例如,如果你有两个值在python中是1.2345和1.2346,而在javascript中有1.2344和1.2347,那么差异分别是1e-4和3 e-4(即一个是另外的3倍)。

所以我会看看你的代码中有减法的地方并检查这些值。你可能会发现你可以(1)重写数学以避免减法(通常事实证明你可以找到一个以某种其他方式计算差异的表达式)或(2)关注为什么这个特定点的值这两种语言之间存在差异(也许是另一种答案所确定的差异以这种方式被放大)。

这也有可能,尽管在这里不太可能,你有所不同,因为在python中某些东西被视为一个整数,但在javascript中被视为浮点数。在python中,整数和浮点数之间存在差异,如果你不小心你可以做一些事情,比如将两个整数除以得到另一个整数(例如python中的3/2 = 1)。而在javascript中,所有数字都是“真正的”浮动,所以这不会发生。

最后,计算的执行方式可能存在细微差别。但这些都是“正常的” - 要获得如此剧烈的差异,你需要像我上面所描述的那样发生。

PS:还要注意Daniel Baulig在上述评论中对参数rd的初始值所说的内容。

答案 1 :(得分:2)

我的猜测是涉及你用于JavaScript版本中某些常量的近似值。特别是你的pi2似乎有点......简短。我相信Python正在使用双精度值。