Excel 16.0 build 19929
Windows, bitness not recorded, CPU not recorded
116 captured inputs are indexed for this environment. Capture dates are not recorded. This is a reading count, not a comparison with another build.
Math and trigonometry functions
Matches all 124 recorded answers
Recorded: 124 workbook cells. How we measure this · See the Rust code
| Language | Name in Excel |
|---|---|
| Arabic | ATAN2 |
| Bulgarian | ATAN2 |
| Czech | ARCTG2 |
| Danish | ARCTAN2 |
| German | ATAN2 |
| Greek | ATAN2 |
| English (Australia) | ATAN2 |
| English (United Kingdom) | ATAN2 |
| English (United States) | ATAN2 |
| Spanish | ATAN2 |
| Estonian | ATAN2 |
| Finnish | ATAN2 |
| French | ATAN2 |
| Hebrew | ATAN2 |
| Croatian | ATAN2 |
| Hungarian | ARCTAN2 |
| Indonesian | ATAN2 |
| Italian | ATAN2 |
| Japanese | ATAN2 |
| Korean | ATAN2 |
| Lithuanian | ATAN2 |
| Latvian | ATAN2 |
| Norwegian | ATAN2 |
| Dutch | ATAN2 |
| Polish | ATAN2 |
| Portuguese (Brazil) | ATAN2 |
| Portuguese (Portugal) | ATAN2 |
| Romanian | ATAN2 |
| Russian | ATAN2 |
| Slovak | ATAN2 |
| Slovenian | ATAN2 |
| Serbian (Latin) | ATAN2 |
| Swedish | ARCTAN2 |
| Thai | ATAN2 |
| Turkish | ATAN2 işlevi |
| Ukrainian | ATAN2 |
| Vietnamese | ATAN2 |
| Chinese (Simplified) | ATAN2 |
| Chinese (Hong Kong) | ATAN2 |
| Chinese (Traditional) | ATAN2 |
Names from Microsoft's support site.
ATAN2(x_num, y_num)
ATAN2(x_num, y_num) is the four-quadrant inverse tangent: the angle from the positive x-axis to
the ray through the origin and the point (x, y).
atan2: R^2 \ {(0,0)} -> (-pi, pi]
Microsoft's Learn reference states the geometry and the range directly: the arctangent is the angle
from the x-axis to a line containing the origin and a point with coordinates (x_num, y_num), and
the angle is given in radians between -pi and pi, excluding -pi.
Excel takes x first. Nearly every other implementation of this function in nearly every other
language — C, Python, Java, JavaScript, Fortran, Rust — takes y first, as atan2(y, x). Excel's
signature is ATAN2(x_num, y_num). Microsoft's Learn parameter table is unambiguous: Arg1 is the
x-coordinate, Arg2 is the y-coordinate.
A formula ported in either direction without swapping the arguments computes the reflection of the
intended angle about the line y = x, which is wrong by an amount that varies with the point and
is therefore not detectable by a spot check. This is the single most consequential fact on the
page and it is why the Handbook states it before the mathematics.
The function is the argument (phase) of the point, the same object as arg(x + iy) in the
complex plane. Microsoft's Learn reference documents it as a set of quadrant identities:
| Condition | Documented identity |
|---|---|
x > 0 | ATAN2(x,y) = ATAN(y/x) |
y >= 0, x < 0 | ATAN2(x,y) = ATAN(y/x) + PI() |
y < 0, x < 0 | ATAN2(x,y) = ATAN(y/x) - PI() |
y > 0, x = 0 | ATAN2(x,y) = PI()/2 |
y < 0, x = 0 | ATAN2(x,y) = -PI()/2 |
x = 0 and y = 0 | returns an error value |
Structural properties:
(-pi, pi]. The value pi is attained (on the negative x-axis with y >= 0) and
-pi is not — the half-open convention that makes the function single-valued.2pi. ATAN2 is
continuous on the plane minus that ray and discontinuous across it; this is not an artefact but
the unavoidable consequence of representing a circle-valued quantity by a real number.atan2(t*x, t*y) = atan2(x, y) for every t > 0. The function depends only on
the direction of the point, not on its magnitude. This is the property that matters most
numerically, and it is the one the departure described below violates.atan2(x, -y) = -atan2(x, y) when y != 0; and atan2(-x, y) = pi - atan2(x, y)
for y > 0.atan2(x, y) = atan(y/x) only for x > 0. The whole
reason the two-argument function exists is that the ratio y/x discards the information needed
to place the quadrant — and, as the next section shows, discards more than that.| Argument | Meaning | Default |
|---|---|---|
x_num | The x-coordinate of the point. Required. | — |
y_num | The y-coordinate of the point. Required. | — |
The misunderstood position is, of course, the order — see above. A secondary one: these are
coordinates, not a slope and a length. ATAN2(1, 1) is pi/4 because the point is on the
diagonal, not because 1/1 = 1.
Returns Number — an angle in radians in (-pi, pi].
x = 0 with y nonzero gives ±pi/2, documented. y = 0 with x > 0 gives
0; y = 0 with x < 0 gives pi — note that the documented identity table routes this
through the y >= 0, x < 0 row, so pi and not -pi, consistent with the half-open range.atan2(-1, +0) is pi and atan2(-1, -0) is
-pi. Whether Excel's value model can express that distinction at all is an open question — see
The value universe — and it interacts with the fact that Excel's
range excludes -pi.This is the substantive finding on the page, and it follows directly from the documented identity table.
Mathematically, the angle of a point is finite for every point except the origin, and depends
only on the point's direction. A genuine two-argument arctangent never forms y/x; it compares
magnitudes and works with the smaller-over-larger ratio, which is always at most 1. Forming y/x
directly reintroduces exactly the overflow the two-argument form exists to avoid: if y is huge
and x is tiny, the quotient overflows to infinity even though the answer is an ordinary angle
very close to ±pi/2.
EV-MATH-0007 and EV-MISC-0013 both carry FUNC.ATAN2 as a subject, and both concern the
same upstream math-deviation row: an error is published exactly when x is nonzero and the
implicit y/x ratio overflows, while the axis case x = 0 — where the ratio is undefined rather
than overflowing — keeps its ±pi/2 value. EV-MISC-0013's own status text puts it plainly: the
four-quadrant angle is finite everywhere off the origin, so this is the ratio being formed first
and the overflow being inherited; a two-argument atan2 would never do it.
Both records carry counts, and both carry a warning the Handbook must repeat rather than
paraphrase away: what was counted is an error-placement boundary, not the bits of the returned
angle. EV-MISC-0013 states that it publishes the weaker reading — the boundary was measured,
not the angle — and that its count rides on the numeric axis only by the register's convention.
The figures are rendered with the records and are not restated here. No claim about the accuracy
of the angle itself follows from either record, and this page makes none.
The documentation predicts the departure. Microsoft's own identity table says
ATAN2(x,y) = ATAN(y/x) for x > 0. Taken as a specification of the evaluation, that identity
requires forming the ratio, and forming it in binary64 requires it to be representable. So the
documented identity and the identified behaviour agree with each other — and both depart from the
mathematical function they claim to compute. That is an unusually clean example of a specification
written in mathematics being implemented as arithmetic.
The second row is the interesting one: an error condition that exists on record and appears in no documentation the Handbook has retrieved.
How a correct two-argument arctangent is built. The standard construction has three steps and never forms a quotient larger than 1:
|x| and |y|. Compute r = min(|x|,|y|) / max(|x|,|y|), which lies in [0, 1] and
cannot overflow. If both are zero, the angle is undefined — that is the only true failure.atan(r), which is the accurate, well-conditioned part.x and y and whether the
swap happened, adding pi/2, pi or negating as required.The construction is total on the punctured plane, never overflows, never underflows in a way that matters, and is accurate for every direction including the extremely elongated ones. IEEE 754 clause 9.2 specifies the behaviour including at zeros and infinities.
Why the ratio form is worse than it looks. Beyond the overflow, y/x loses the homogeneity
property: atan2(t*x, t*y) should be independent of t, and forming a quotient makes it depend on
whether that quotient happens to be representable. So a formula that scales its coordinates — a
completely ordinary thing to do — can change its answer from an angle to an error. There is no
scaling that fixes it in general, because the failing cases are exactly the ones with extreme
aspect ratios.
Underflow is the mirror hazard. If y is tiny and x is huge, y/x underflows to zero and
the angle comes back as exactly 0 or pi rather than as a tiny nonzero angle. That is the same
defect at the other end, and it produces a wrong number rather than an error — the worse of the
two outcomes. Whether it occurs is a separate question from the overflow, and the Handbook does not
know the answer for Excel; no record addresses it.
The pi constant appears twice. The quadrant adjustments add pi or pi/2. As with ATAN,
a careful implementation uses a two-part split constant so the addition does not eat the accuracy
of a result that may be small. An angle just below pi computed as pi_double - small inherits
the representation error of pi_double.
Signed zero decides the cut. atan2(-1, +0) = pi and atan2(-1, -0) = -pi under IEEE; this is
how the standard lets a computation stay on the correct side of the branch cut. Excel's documented
range excludes -pi, which means either that the distinction is not expressible or that the
documented range is approximate. Nobody has checked which.
Quoted from the public repository DnaCalc/DnaCalc, crates calc-func and calc-fml, at commit 9e1884369a67. Comments are the source's own. A kernel shared with other functions appears once, on its module page.
ATAN2 · 3 lines · calc-func/src/catalogue/math.rs on GitHub8 atan2 "ATAN2" (2, 2) [V "x_num", V "y_num"] |s, a, sv| {
binary(s, a, k::atan2::atan2_kernel)
}
atan2_kernel · 26 lines · calc-func/src/ported/atan2.rs on GitHubpub fn atan2_kernel(x_num: f64, y_num: f64) -> Result<f64, WorksheetErrorCode> {
if x_num == 0.0 && y_num == 0.0 {
return Err(WorksheetErrorCode::Div0);
}
// Excel returns #NUM! when the implicit y/x ratio overflows to infinity
// (x != 0 and |y| >> |x|), e.g. ATAN2(1e-200, 1e109). A finite ratio stays a
// number, and the axis case x == 0 (ratio undefined, not overflowing) keeps
// its ±pi/2 value. Pinned against live Excel 16.0 b20026 (BUG-FUNC-027 B3).
if x_num != 0.0 && (y_num / x_num).is_infinite() {
return Err(WorksheetErrorCode::Num);
}
// Excel's angle is the arctangent of the binary64 ratio y/x, moved by pi into the left
// half-plane (dc-j9k: 15 of 15 sweep readings and the catalogue oracle's ATAN2 rows of sheet
// dcj9k_math; the correctly rounded atan2 matched 10 of 15). On the y axis it is ±pi/2.
if x_num == 0.0 {
return Ok(std::f64::consts::FRAC_PI_2.copysign(y_num));
}
let angle = crate::ported::excel_numeric::excel_atan(y_num / x_num);
Ok(if x_num > 0.0 {
angle
} else if y_num >= 0.0 {
angle + std::f64::consts::PI
} else {
angle - std::f64::consts::PI
})
}
excel_atan · 13 lines · calc-func/src/ported/excel_numeric/mod.rs on GitHub/// Direct public FPATAN operation retained for separately characterized callers
/// and research comparisons. W111's ATAN and revised imaginary-family callers
/// use the magnitude-reduced graph below.
pub(crate) fn excel_atan(x: f64) -> f64 {
#[cfg(all(target_arch = "x86_64", not(feature = "soft-x87")))]
{
x87::atan(x)
}
#[cfg(not(all(target_arch = "x86_64", not(feature = "soft-x87"))))]
{
atan_with::<Soft>(x)
}
}
binary catalogue/mathatan_with ported/excel_numericpack_raw ported/excel_numeric/soft87zero ported/excel_numeric/soft87inf ported/excel_numeric/soft87pack ported/excel_numeric/soft87ext_one ported/excel_numeric/soft87atan ported/excel_numeric/x87No implementation has been published with a Handbook test suite for this function.
The recorded environments below distinguish a reading from a same-input comparison. Counts describe captured inputs in each environment; overlapping captures and comparisons are not totals of unique worksheet calls.
| Excel 16.0 build | Platform and CPU | Captured inputs |
|---|---|---|
| 19929 | Windows, bitness not recorded, CPU not recorded | 116 |
The record contains no same-input comparison between these environments. Reading different inputs on different builds does not establish either a version change or cross-build agreement.
Recorded environments and comparison details.
Windows, bitness not recorded, CPU not recorded
116 captured inputs are indexed for this environment. Capture dates are not recorded. This is a reading count, not a comparison with another build.
ATAN — the one-argument form. ATAN2(x, y) = ATAN(y/x) for x > 0 only, and the
restriction is the reason ATAN2 exists. Note that ATAN itself never overflows, because the
caller has already done the division and taken the consequences.ACOT — ACOT(x) = ATAN2(x, 1) in Excel's order, and that formulation is better conditioned
at large |x| than PI()/2 - ATAN(x). See the ACOT page.IMARGUMENT — the complex-number surface computing the same quantity, arg(x + iy). If the
two disagree anywhere, one of them is wrong, and that is a cheap cross-check the Handbook has not
run.ASIN / ACOS — both are better computed through ATAN2 than through their own closed
forms when the endpoints matter: asin(t) = ATAN2(SQRT(1-t^2), t) and
acos(t) = ATAN2(t, SQRT(1-t^2)) in Excel's order.DEGREES — the usual consumer; the Learn reference gives the 180/PI() remark.SQRT, SUMSQ — the magnitude half of a polar conversion, of which ATAN2 is the angle
half.ATAN, whenever the quadrant matters; and with every other language's
atan2, whose argument order is reversed.No named variants are recorded yet.
Suggest a correction or contribute an implementation · For agents