2

私は、緯度/経度座標が与えられた地球表面上の 2 点間の距離を計算する、PC 上で実行される Visual C++ で記述された、長年確立されたルーチンを持っています。

これを Android への移植の一環として Java に変換しましたが、結果が異なります。この理由を調査するために、複雑な三角方程式をビットに分割して、各ステップで何が起こっているかを追跡しました。

ただし、Visual C++ では、段階的な計算の結果は、複雑なステートメントから得られた結果とは異なりますが、明らかに同じである必要があります。理由が知りたいです!

予想どおり、Java バージョンは両方のケースで同じ結果をもたらします。

Visual C++ コードは次のとおりです。

double CCoord::GetDistanceRadians(double dLatRadians, double dLongRadians)
{
    double dResult;

    // This is the step by step code
    double r1, r2, r3, r4, r5;
    r1 = sin(m_dLatRadians);
    r2 = sin(dLatRadians);
    r3 = cos(dLatRadians);
    r4 = m_dLongRadians - dLongRadians;
    r5 = cos(r4);

    r1 *= r2;
    r2 = r3 * r3;
    r2 *= r5;
    r4 = r1 + r2;

    // This is the original statement: r4 and dResult should be equal
    // (but they aren't)
    dResult = sin(m_dLatRadians) * sin(dLatRadians) +
        cos(m_dLatRadians) * cos(dLatRadians) * cos(m_dLongRadians - dLongRadians);

    // Protect against maths processor inaccuracies
    if ((dResult > 1.0) || (dResult < -1.0))
        dResult = 0.0;
    else
        dResult = acos(dResult);

    return dResult;
}

Javaコードは次のとおりです。

    // Return angular distance in radians
private double getDistanceRadians(double dLatRadians, double dLongRadians)
{
    double result;

    // Do JIT test
    checkRadianValues();

            // This is the step by step code
    double r1, r2, r3, r4, r5;
    r1 = Math.sin(m_dLatRadians);
    r2 = Math.sin(dLatRadians);
    r3 = Math.cos(dLatRadians);
    r4 = m_dLongRadians - dLongRadians;
    r5 = Math.cos(r4);

    r1 *= r2;
    r2 = r3 * r3;
    r2 *= r5;
    r4 = r1 + r2;

    // This is the original statement: r4 and result should be equal
    // (and they are)
    result = Math.sin(m_dLatRadians) * Math.sin(dLatRadians) +
                Math.cos(dLatRadians) * Math.cos(dLatRadians) *
                Math.cos(m_dLongRadians - dLongRadians);

    // Protect against maths processor inaccuracies
    if ((result > 1.0d) || (result < -1.0d))
        result = 0.0d;
    else
        result = Math.acos(result);

    return result;
}

入力値と結果値は次のとおりです。

Variable         VC++ value         Java value
m_dLatRadians    0.896808347        0.896808378
m_dLongRadians  -0.047414778(0)    -0.047414778(6)
dLatRadians      0.896192633(9)     0.896192588(9)
dLongRadians    -0.026897463       -0.026897463
r4               1.000218106        1.0002181433
dResult/result   0.999917766        1.0002181433

Visual C++ バージョンで r4 と dResult が異なる理由を誰か教えてください。

PS VC++ バージョンからは良好な最終距離結果が得られ、Java からは悪い最終結果が得られます - ほぼすべての距離がゼロになります (これらのルーチンを呼び出す上位レベルのコードは、たくさんあるため表示されません! ただし、不一致です)について調べることに興味があります)。

4

1 に答える 1

1

C++ コード内

cos(m_dLatRadians) * cos(dLatRadians)

する必要があります

cos(dLatRadians) * cos(dLatRadians)

r2 = r3 * r3;Javaで行っていることと一貫性があり、一致すること。

また、@ CaseyBが指摘するように、dLatRadiansパラメーターは異なります (そのままm_dLatRadians)。

于 2012-09-19T21:07:21.327 に答える