如何划分微小的双precision号码不正确precision错误? [英] How to divide tiny double precision numbers correctly without precision errors?

查看:109
本文介绍了如何划分微小的双precision号码不正确precision错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图诊断并解决其归结为X / Y产生不稳定的结果,当X和Y是一个小错误:

I'm trying to diagnose and fix a bug which boils down to X/Y yielding an unstable result when X and Y are small:

在这种情况下,既CX和patharea增加顺利。它们的比值是一个光滑的渐近线高的数字,但飘忽不定的小的数字。最明显的首先想到的是,我们达到浮点精度的限制,但实际数字本身都远不及它。动作编号的类型是IEE 754双precision花车,所以应该有precision 15十进制数字(如果我没有看错)。

In this case, both cx and patharea increase smoothly. Their ratio is a smooth asymptote at high numbers, but erratic for "small" numbers. The obvious first thought is that we're reaching the limit of floating point accuracy, but the actual numbers themselves are nowhere near it. ActionScript "Number" types are IEE 754 double-precision floats, so should have 15 decimal digits of precision (if I read it right).

分母的一些典型值(patharea):

Some typical values of the denominator (patharea):

0.0000000002119123
0.0000000002137313
0.0000000002137313
0.0000000002155502
0.0000000002182787
0.0000000002200977
0.0000000002210072

和分子(CX):

0.0000000922932995
0.0000000930474444
0.0000000930582124
0.0000000938123574
0.0000000950458711
0.0000000958000159
0.0000000962901528
0.0000000970442977
0.0000000977984426

每个这些增加单调,但正如上面看到的比例是混乱的。

Each of these increases monotonically, but the ratio is chaotic as seen above.

在更大的数字就平息平稳双曲线。

At larger numbers it settles down to a smooth hyperbola.

所以,我的问题:什么是处理非常小的数字,当你需要把一个被另一个正确的方法

我还以为1000提前乘以分子和/或分母的,但不能完全工作了。

I thought of multiplying numerator and/or denominator by 1000 in advance, but couldn't quite work it out.

实际的code的问题是,重新计算()函数的此处。它计算多边形的质心,但是当多边形是微小的,质心跳不规则左右的地方,并可以结束了从多边形长的距离。数据系列以上是移动多边形的一个节点中一致的方向的结果(通过手,这就是为什么它不是完全光滑的)。

The actual code in question is the recalculate() function here. It computes the centroid of a polygon, but when the polygon is tiny, the centroid jumps erratically around the place, and can end up a long distance from the polygon. The data series above are the result of moving one node of the polygon in a consistent direction (by hand, which is why it's not perfectly smooth).

这是Adobe的Flex 4.5。

This is Adobe Flex 4.5.

推荐答案

我认为最有可能是由下面一行在code导致此问题:

I believe the problem most likely is caused by the following line in your code:

sc = (lx*latp-lon*ly)*paint.map.scalefactor;

如果您的多边形是非常小的,那么 LX LON 几乎是相同的,因为是 LY latp 。他们都是非常大的比较结果,所以你减去两个数字几乎相等。

If your polygon is very small, then lx and lon are almost the same, as are ly and latp. They are both very large compared to the result, so you are subtracting two numbers that are almost equal.

要解决这个问题,我们可以利用这样一个事实:

To get around this, we can make use of the fact that:

x1*y2-x2*y1 = (x2+(x1-x2))*y2 - x2*(y2+(y1-y2))
            = x2*y2 + (x1-x2)*y2 - x2*y2 - x2*(y2-y1)
            = (x1-x2)*y2 - x2*(y2-y1)

那么,试试这个:

So, try this:

dlon = lx - lon
dlat = ly - latp
sc = (dlon*latp-lon*dlat)*paint.map.scalefactor;

的值在数学上是相同的,但条件是幅度小的顺序,所以其误差应一个数量级较小以及

The value is mathematically the same, but the terms are an order of magnitude smaller, so the error should be an order of magnitude smaller as well.

这篇关于如何划分微小的双precision号码不正确precision错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆