Java中计算天体视差改正的数学错误

Java中计算天体视差改正的数学错误,java,math,astronomy,Java,Math,Astronomy,我正在实施这本书的计算。到目前为止,我的计算结果与书中的示例计算结果完全相同 然而,在第39条“计算视差修正”中,我遇到了一个我无法理解的差异 手头的任务描述如下: static EquatorialCoordinate parallax(EquatorialCoordinate body, ObserverLocation observer, ZonedDateTime zdt, double P) { double Hd = 15d * raha(body.α, zdt, o

我正在实施这本书的计算。到目前为止,我的计算结果与书中的示例计算结果完全相同

然而,在第39条“计算视差修正”中,我遇到了一个我无法理解的差异

手头的任务描述如下:

    static EquatorialCoordinate parallax(EquatorialCoordinate body, ObserverLocation observer, ZonedDateTime zdt, double P) {
    double Hd = 15d * raha(body.α, zdt, observer.λ);
    step("α", body.α);
    step("δ", body.δ);
    step("φ", observer.φ);
    step("λ", observer.λ);
    step("h", observer.h);
    step("H", Hd);

    double H = toRadians(Hd);
    Parallax ρ = parallax(observer.φ, observer.h);

    step("P", P);
    P = toRadians(P);

    double δ = toRadians(body.δ);
    double r = 1d / sin(P);
    step("r", r);
    double ρsinφ = ρ.sin;
    double ρcosφ = ρ.cos;
    step("ρcosφ'",ρcosφ);
    step("ρsinφ'",ρsinφ);
    double Δ = atan((ρcosφ * sin(H)) / ((r * cos(δ)) - (ρcosφ * cos(H))));
    step("Δ", toDegrees(Δ));
    H += Δ;
    step("H'", toDegrees(H));
    Δ = toDegrees(Δ);
    double α$ = body.α - (Δ / 15d);
    step("α'", α$);

    double divident = (r * sin(δ)) - ρsinφ;
    double divisor = ( r * cos(δ) * cos(H) ) - ρcosφ;
    double δ$ = atan(cos(H) * (divident / divisor));
    δ$ = toDegrees(δ$);
    step("δ'", δ$);
    return new EquatorialCoordinate(α$, δ$);
}
举个例子,让我们计算一下26日月球的视赤经和赤纬 1979年2月16时45米UT,从海拔60米的位置观测,经度为100°W,纬度为50°N。地心坐标为α=22h 35m 19s,δ=−7°41′13′,月球赤道水平视差为1°01′09′

本书对计算顺序的描述如下:

然而,我第7步的结果是−31.993415,但书上说−31,994415。如果我用计算器计算第7步的数学,结果是−31.993415,所以我的结果似乎是对的,而这本书是错的

我可以接受,但第10步也有不同。我的结果是-8570634,书本的结果是-8.538165,差别很大。我一遍又一遍地阅读步骤10,看看我的代码中是否有错误,但我没有看到

到目前为止,我的计算和书本上的计算完全一样,我被卡住了。我是做错了什么(首选),还是这本书出错了(希望不会再有了……)

此函数的Java代码如下所示:

    static EquatorialCoordinate parallax(EquatorialCoordinate body, ObserverLocation observer, ZonedDateTime zdt, double P) {
    double Hd = 15d * raha(body.α, zdt, observer.λ);
    step("α", body.α);
    step("δ", body.δ);
    step("φ", observer.φ);
    step("λ", observer.λ);
    step("h", observer.h);
    step("H", Hd);

    double H = toRadians(Hd);
    Parallax ρ = parallax(observer.φ, observer.h);

    step("P", P);
    P = toRadians(P);

    double δ = toRadians(body.δ);
    double r = 1d / sin(P);
    step("r", r);
    double ρsinφ = ρ.sin;
    double ρcosφ = ρ.cos;
    step("ρcosφ'",ρcosφ);
    step("ρsinφ'",ρsinφ);
    double Δ = atan((ρcosφ * sin(H)) / ((r * cos(δ)) - (ρcosφ * cos(H))));
    step("Δ", toDegrees(Δ));
    H += Δ;
    step("H'", toDegrees(H));
    Δ = toDegrees(Δ);
    double α$ = body.α - (Δ / 15d);
    step("α'", α$);

    double divident = (r * sin(δ)) - ρsinφ;
    double divisor = ( r * cos(δ) * cos(H) ) - ρcosφ;
    double δ$ = atan(cos(H) * (divident / divisor));
    δ$ = toDegrees(δ$);
    step("δ'", δ$);
    return new EquatorialCoordinate(α$, δ$);
}
“step”函数执行一个简单的格式化printf。该程序的输出为:

  • α22.588611
  • δ-7.686944
  • φ50.000000
  • λ-100.000000
  • h 60.000000
  • H-31.642500
  • 第1.019167页
  • r 56.221228
  • ρcosφ'0.644060
  • ρsinφ'0.762422
  • Δ-0.350915
  • H'-31.993414
  • α'22.612005
  • δ'-8.570634
由此产生的δ’为-8°34'14.28“,而不是-8°32'17”

我已经用books值替换了我计算的H'值,以查看该书是否包含携带的错误,但即使我这样做,该值也是错误的

因此。。。我最大的问题是,我的实现是错误的(在哪里,我看不到),还是书中的计算是错误的

(编辑:)类使用java.util.StrictMath用strictfp注释。

您编写

H += Δ;
这会改变H的值

然后你写

double δ$ = atan(cos(H) * (divident / divisor));

当它应该使用旧值时,它使用了新版本的H。

多亏了@svasa,我发现步骤10的除数应该包含H,而不是H'。 正确的代码是:

static EquatorialCoordinate parallax(EquatorialCoordinate body, ObserverLocation observer, ZonedDateTime zdt, double P) {
    double H = toRadians(15d * raha(body.α, zdt, observer.λ));
    P = toRadians(P);
    Parallax ρ = parallax(observer.φ, observer.h);
    double δ = toRadians(body.δ);
    double r = 1d / sin(P);
    double Δ = atan((ρ.cosφ * sin(H)) / ((r * cos(δ)) - (ρ.cosφ * cos(H))));
    double H$ = H + Δ; 
    double α$ = body.α - (toDegrees(Δ) / 15d);
    double δ$ = toDegrees(atan(cos(H$) * ((r * sin(δ) - ρ.sinφ) / (r * cos(δ) * cos(H) - ρ.cosφ))));

    return new EquatorialCoordinate(α$, δ$);
}

假设您的计算是正确的,这很可能是由于
double
计算中的重复错误造成的。试着用一个
BigDecimal
。我有个问题。您是如何在java代码中键入这些符号的?我附议:这里有一些繁重的计算,使用浮点数会导致精度错误。使用
BigDecimal
应该会有帮助。@svasa Java编译器接受unicode,因为这些“符号”是希腊字符,所以它们是有效的变量名。你可以用它写一些讨厌的东西(我记得有人在这里用阿拉伯语写代码,在ltr和rtl之间切换)-你能做到这一点并不意味着你应该做到;)@Thomas那么你是如何在代码中输入这些符号的,你使用一些特殊的键盘吗?或者写一些像U+10400的东西?