ACOT with a negative argument: Google Sheets uses atan(1/x), Excel and LibreOffice use pi + atan(1/x) (executed)
ACOT returns the angle whose cotangent is the number you hand it — the
arccotangent, in radians. For a positive argument every engine returns the same thing. For a
negative argument they split into two camps, and nothing errors. Microsoft
documents an angle “in radians in the range 0 (zero) to pi”, LibreOffice Calc documents
“The angle returned is between 0 and PI” and returns exactly that, and
Google Sheets returns the angle from the other branch — the same direction,
lower by exactly π.
Our corpus case is =ROUND(ACOT(-2),9). It comes back as
2.677945045 in Excel for the web and in all four LibreOffice builds we execute, and
as -0.463647609 in Google Sheets. The difference is 3.141592654: π radians, or
180 degrees.
The surprise
This is a silent divergence. No #NUM!, no #NAME?,
no red triangle — both engines return a perfectly ordinary number, and the two numbers
describe directions that point opposite ways. Every negative input is affected and the offset is
always the same: exactly π. Wrap the call in DEGREES and the divergence becomes
legible as what it is: =DEGREES(ACOT(-1)) is 135 degrees under the
documented range and -45 degrees in Google Sheets. A bearing, a heading, a slope
angle or a rotation computed with ACOT over a column that can go negative therefore
points 180 degrees the wrong way when the file changes application, with nothing on screen to say
so. Positive inputs agree to full precision, so a spot check on friendly data finds nothing.
A minimal example
| Formula | Excel, desktop (documented) | Excel for the web | Google Sheets | LibreOffice Calc 25.8.7.3 (executed) |
|---|---|---|---|---|
| =ROUND(ACOT(-2),9) | 2.677945045 | 2.677945045 (executed 2026-09-01) | -0.463647609 (executed 2026-08-31) | 2.677945045 |
| =ROUND(ACOT(-1),9) | 2.35619449 | — | -0.785398163 (hand-checked 2026-09-04) | 2.35619449 |
| =ROUND(ACOT(-0.5),9) | 2.034443936 | — | -1.107148718 (hand-checked 2026-09-04) | 2.034443936 |
| =ROUND(ACOT(-10),9) | 3.041924001 | — | -0.099668652 (hand-checked 2026-09-04) | 3.041924001 |
| =ROUND(DEGREES(ACOT(-1)),6) | 135 | — | -45 (hand-checked 2026-09-04) | 135 |
| =ROUND(ACOT(1),9) (control) | 0.785398163 | — | 0.785398163 (hand-checked 2026-09-04) | 0.785398163 |
| =ROUND(ACOT(0),9) (control) | 1.570796327 | 1.570796327 (executed 2026-09-01) | 1.570796327 (executed 2026-08-31) | 1.570796327 |
| =ROUND(ACOT(2),4) (control) | 0.4636 | 0.4636 (executed 2026-09-01) | 0.4636 (executed 2026-08-31) | 0.4636 |
The three control rows are the point of the table as much as the diverging ones. At
x = 1, x = 0 and x = 2 every engine returns the same value to
nine decimal places; the split appears only once the argument goes below zero, and then it appears
for every negative argument tested, small or large. The LibreOffice column is what our harness read
back after recalculating the workbook, and 24.2.0.3, 24.8.7.2, 25.2.0.3 and 25.8.7.3 all
returned identical values, so this is a settled convention rather than a version
difference.
Read the provenance of each column literally. The Excel, desktop column is documentation,
not measurement: ACOT(2) = 0.4636 is the worked example printed on Microsoft’s
page, and the rest of that column is the arithmetic its stated 0-to-π range forces
(π + atan(1/x) for negative x), recorded as the expected value in our test
corpus. The Excel for the web column is our dated recalculation run on OneDrive; a dash
means the formula is outside the corpus that run covered, so there is no measurement to publish and
we are not guessing one. Google Sheets figures marked “executed” come from our dated
Drive-import run; those marked “hand-checked” were typed into a live Google sheet on
2026-09-04 and read back off the grid, which is weaker provenance than a harness run and is labelled
so.
Two conventions for one function
The arccotangent is genuinely ambiguous. Cotangent repeats every π, so “the angle whose cotangent is -2” has infinitely many answers and an implementation has to pick a branch. There are two obvious choices:
- The
atan(1/x)branch, which lands in(-π/2, π/2)and is what you get by inverting the reciprocal directly. This is what Google Sheets returns. - The
π + atan(1/x)branch for negative x, which keeps every result inside(0, π)— a continuous half-turn of directions with no jump at zero. This is what Microsoft documents, and what LibreOffice documents and executes.
Both are correct arccotangents; they differ by one period. You can watch the two conventions
being assembled out of ATAN, which agreed to the last digit in all three executed
engines on every ATAN case in our corpus:
| Formula | LibreOffice Calc 25.8.7.3 (executed 2026-09-04) | Google Sheets | What it shows |
|---|---|---|---|
| =ROUND(ATAN(1/-2),9) | -0.463647609 | — | the bare atan(1/x) branch — digit for digit what Google Sheets returns for ACOT(-2) |
| =ROUND(PI()-ATAN(2),9) | 2.034443936 | — | π + atan(1/-0.5) spelled out — digit for digit the ACOT(-0.5) above |
| =ROUND(PI()/2-ATAN(-2),9) | 2.677945045 | — | the portable one-term form of the documented branch, equal to ACOT(-2) |
| =ROUND(ATAN2(-2,1),9) | 2.677945045 | — | ATAN2 reaches the documented branch too, by quadrant |
| =ROUND(ACOT(-2)-ACOT(2),9) | 2.214297436 | -0.927295218 (hand-checked 2026-09-04) | the gap between the engines: 2.214297436 − (-0.927295218) = 3.141592654 = π |
These five rows are one-off probes executed on LibreOffice 25.8.7.3 on 2026-09-04, not corpus cases, so they do not appear on the function pages. A dash in the Google Sheets column marks a formula we never typed into a live sheet; it is a gap in our evidence, not a failure there. The last row is the cleanest statement of the divergence: the same subtraction, over the same two arguments, differs between the two engines by exactly π, because the negative half of the expression sits on a different branch in each.
What each app documents
Microsoft’s ACOT
reference is unambiguous: “The returned angle is given in radians in the range 0 (zero) to
pi”, with the worked example =ACOT(2) giving 0.4636 and a pointer to
DEGREES for converting the result. LibreOffice’s
Calc help says
the same thing in its own words — “The angle returned is between 0 and PI” —
and its published example, “=ACOT(1) returns 0.785398163397448 (PI/4 radians)”, matches
what our harness read back.
Google’s ACOT documentation is
the interesting one, because it contradicts itself. Its Notes section states that
“ACOT returns results that are between 0 and π (pi)” — the Microsoft rule,
copied. But the worked examples printed further down the same page list
=ACOT(-4) as -0.2449786631 and =DEGREES(ACOT(A3)) with
A3 = -4 as -14.03624347, both of which are outside the range the page has
just promised. The examples, not the Notes, describe the behaviour we measured: Sheets is on the
atan(1/x) branch. So there is no engine here whose documentation you can simply trust
about negative arguments — one page says one thing and shows another.
Function pages with the full executed matrix: ACOT, ATAN, ATAN2, DEGREES.
The portable fix
Do not let the branch be chosen for you by whichever application opened the file. Write the convention you want into the formula. For the Microsoft/LibreOffice range, the shortest portable spelling is a single subtraction:
=PI()/2-ATAN(A1)
That is a mathematical identity rather than a measured result, and it holds for every real
x: atan(x) + atan(1/x) is π/2 when x is positive and
-π/2 when it is negative, so π/2 - atan(x) equals
atan(1/x) above zero and π + atan(1/x) below it — precisely the
documented branch — and it gives π/2 at x = 0, where
1/x does not exist at all. Our probe row above,
=ROUND(PI()/2-ATAN(-2),9) returning 2.677945045 on LibreOffice, is that identity
executed at one point.
=ATAN2(A1,1) is a second portable spelling of the same branch: it asks for the angle
of the point (A1, 1), which for a negative A1 lies in the second quadrant, between
π/2 and π. Because the second argument is the constant 1, it can
never hit the degenerate origin case where the engines part company again — see
ATAN2(0,0) for that one.
If you would rather keep the branch visible in the formula, write it out:
=IF(A1<0,PI()+ATAN(1/A1),IF(A1=0,PI()/2,ATAN(1/A1))). And if the
atan(1/x) convention is the one your model wants, =ATAN(1/A1) writes it
out explicitly — just guard A1 = 0, where the reciprocal divides by zero while
ACOT(0) is π/2 in every engine we execute.
Two migration habits follow. When a workbook moves between the apps, grep it for
ACOT and check whether the argument column can go negative; if it cannot, nothing here
touches you. If it can, convert the result to degrees in a scratch cell before and after the move —
a 180-degree shift is much easier to see than a 3.14 shift in radians, and it is the only symptom
you will get.
Check before you migrate
A note on which Excel this is. The Excel column in the tables above is Microsoft’s documented behaviour for desktop Excel, as recorded in our test corpus — we do not run desktop Excel, and no value in that column is a measurement. Excel for the web is a different application with its own calculation engine, and that one we do run (recalculated on OneDrive, 2026-09-01); it returned 2.677945045 for ACOT(-2), matching documented desktop Excel and all four LibreOffice builds, and unlike Google Sheets. Only the corpus cases that existed when that run was made were covered by it, which is why the other rows in its column are dashes. Because we have no desktop run to compare against, a disagreement between an Excel-web measurement and the documented column is genuinely ambiguous: it may mean the web engine diverges from the desktop one, or that the documentation is wrong about both. We do not claim to know which.