Skip to content

fix(nl): NL(87°) returns 2 per DO-260B §A.1.7.2, not 1#2

Open
willi-werner wants to merge 1 commit into
nasa:masterfrom
willi-werner:fix/nl-87deg-polar-boundary-do260b
Open

fix(nl): NL(87°) returns 2 per DO-260B §A.1.7.2, not 1#2
willi-werner wants to merge 1 commit into
nasa:masterfrom
willi-werner:fix/nl-87deg-polar-boundary-do260b

Conversation

@willi-werner

Copy link
Copy Markdown

Problem

nl_double(87.0) returns NL=1 but RTCA DO-260B §A.1.7.2 mandates NL(87°) = 2.

The first comparison threshold was 86.99999999999998578914 — this is nextafter(87.0, 0.0) in IEEE 754, the largest representable double strictly less than 87.0. Therefore fabs(87.0) > 86.9999... is true, and the function misclassifies the exact 87° boundary point into the polar-cap zone (NL=1) instead of the adjacent zone (NL=2).

Standard reference

RTCA DO-260B / EUROCAE ED-102A, §A.1.7.2 defines these points explicitly:

  • NL(+87°) = 2
  • NL(−87°) = 2
  • NL(lat > +87°) = 1
  • NL(lat < −87°) = 1

The 87° point belongs to the NL=2 zone; only latitudes strictly above 87° return NL=1.

Fix

Change the threshold to exactly 87.0:

// before
return abslat > 86.99999999999998578914? 1 :
// after
return abslat > 87.0? 1 :

87.0 is exactly representable in IEEE 754 double precision (it is a small integer), so there is no precision loss. The comment added to the source cites the standard section so the intent is unambiguous.

Testing

Verify with a simple unit check:

assert(nl_double(87.0)  == 2);
assert(nl_double(-87.0) == 2);
assert(nl_double(87.01) == 1);
assert(nl_double(-87.01) == 1);

Closes #1

Credit

Bug discovered by @mrksngl.

The first threshold in nl_double() was 86.99999999999998578914, which
is the largest IEEE 754 double strictly below 87.0. This caused
fabs(87.0) > 86.999... to evaluate as true, returning NL=1 for the
exact 87° latitude point.

DO-260B §A.1.7.2 defines the following boundary points explicitly:
  NL(+87°) = 2,  NL(−87°) = 2
  NL(lat > +87°) = 1,  NL(lat < −87°) = 1

The standard therefore includes 87° in the NL=2 zone. The correct
threshold is exactly 87.0, so that the boundary point itself falls
through to NL=2 and only strictly polar latitudes return NL=1.

Finder: @mrksngl
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

nl_double(87.0) returns NL=1; should return NL=2 per DO-260B §A.1.7.2

1 participant