2025, Nov 03 07:00
Find Equal Sums of Two Fourth Powers in Python with Integer Base Checks and Tight Tolerance
Identity-based Python method to find equal fourth powers: enforce integer bases, compare sides with tight tolerance, avoid floating-point near misses safely.
Equal sums of fourth powers are notoriously hard to find. A compact identity reduces the usual four-variable search to just three integers k, n, x, and from those three produces four expressions whose fourth powers satisfy a taxicab-type equality. The catch is practical: naive floating-point evaluation will happily return many near-misses, and without explicit checks you will admit non-integers for the underlying bases. Below is a focused walkthrough of getting a robust search in Python that returns triples (k, n, x) only when all four bases are integers and the equation balances within a strict tolerance.
Setup: the search target and a baseline
The identity yields four expressions depending on n, k, x. The goal is to find positive integers n, k, x such that each of those four expressions is a perfect fourth power and the sum on the left equals the sum on the right. For example, with n = 24, k = 74, x = 300783360 the identity specializes to 158^4 + 59^4 = 134^4 + 133^4, where each fourth root is an exact positive integer. That’s exactly the kind of hit we want the code to find.
A straightforward implementation computes both sides numerically but doesn’t enforce that each base is integral. That’s why it returns many false positives. Here’s an illustrative baseline that mirrors that behavior.
import math
# cube-root constants
r13 = (1.0 / 3.0) ** (1.0 / 3.0)
r13_2 = (1.0 / 3.0) ** (2.0 / 3.0)
def root3(val):
if val >= 0:
return val ** (1.0 / 3.0)
else:
return -(-val) ** (1.0 / 3.0)
def core(term, X):
return (
3.0 * term ** 3
- 3.0 * (term ** 4 - X) / term
+ math.sqrt((1.0 / 3.0) * term ** 8 + 9.0 * X ** 2) / term
)
def sum_left(N, K, X):
Rn = root3(core(N, X))
Rk = root3(core(K, X))
A = (-0.5 * (r13 * N) ** 2 / Rn + 0.5 * N + 0.5 * r13 * Rn) ** 4
B = (-0.5 * r13_2 * K ** 2 / Rk - 0.5 * K + 0.5 * r13 * Rk) ** 4
return A + B
def sum_right(N, K, X):
Rn = root3(core(N, X))
Rk = root3(core(K, X))
C = (-0.5 * (r13 * N) ** 2 / Rn - 0.5 * N + 0.5 * r13 * Rn) ** 4
D = (-0.5 * r13_2 * K ** 2 / Rk + 0.5 * K + 0.5 * r13 * Rk) ** 4
return C + D
This version can report very small left–right differences, but it does not guarantee that the four bases themselves are integers. That was the core issue.
What actually goes wrong
There are two problems intertwined. First, without extracting and checking the bases before taking the fourth power, you cannot enforce that each term is a perfect fourth power. Second, even if the identity is correct algebraically, floating-point evaluation introduces tiny discrepancies; if you only compare the two sums, you can get near-zero errors for non-integral bases, which are not acceptable if you’re after exact integer fourth powers.
The fix: check the four bases explicitly
The practical remedy is simple and effective. Compute the four bases explicitly on the left and right, check that each one is numerically an integer within a tight tolerance, and then compare the two sides. The key is to return the bases alongside the sums, and validate them. If you also want the four bases to be positive, add that constraint too.
import math
# cube-root constants
r13 = (1.0 / 3.0) ** (1.0 / 3.0)
r13_2 = (1.0 / 3.0) ** (2.0 / 3.0)
def root3(val):
if val >= 0:
return val ** (1.0 / 3.0)
else:
return -(-val) ** (1.0 / 3.0)
def core(term, X):
return (
3.0 * term ** 3
- 3.0 * (term ** 4 - X) / term
+ math.sqrt((1.0 / 3.0) * term ** 8 + 9.0 * X ** 2) / term
)
def left_terms(N, K, X):
Rn = root3(core(N, X))
Rk = root3(core(K, X))
u1 = (-0.5 * r13_2 * N ** 2 / Rn + 0.5 * N + 0.5 * r13 * Rn)
u2 = (-0.5 * r13_2 * K ** 2 / Rk - 0.5 * K + 0.5 * r13 * Rk)
A = u1 ** 4
B = u2 ** 4
return A + B, u1, u2
def right_terms(N, K, X):
Rn = root3(core(N, X))
Rk = root3(core(K, X))
u3 = (-0.5 * r13_2 * N ** 2 / Rn - 0.5 * N + 0.5 * r13 * Rn)
u4 = (-0.5 * r13_2 * K ** 2 / Rk + 0.5 * K + 0.5 * r13 * Rk)
C = u3 ** 4
D = u4 ** 4
return C + D, u3, u4
def intlike(val, tol=1e-12):
return abs(val - round(val)) < tol
# Example targeted search with the known (N, K)
count = 0
limit = 1000
EPS = 1e-6
for N in range(24, 25):
for K in range(74, 75):
for X in range(1, 300790000):
try:
left_sum, a1, a2 = left_terms(N, K, X)
right_sum, b1, b2 = right_terms(N, K, X)
err = abs(left_sum - right_sum)
if err < EPS:
if intlike(a1) and intlike(a2) and intlike(b1) and intlike(b2):
# If you also need all-positive bases, add: and a1 > 0 and a2 > 0 and b1 > 0 and b2 > 0
count += 1
print(
f"hit: n={N} k={K} x={X} error={err:.2e} "
f"bases=({a1}, {a2}, {b1}, {b2})"
)
if count >= limit:
raise StopIteration
except StopIteration:
raise
except Exception:
continue
This enforces exactly what the problem needs: each of the four bases must be integer-valued, and the left–right equality must match to a tight tolerance. With n = 24 and k = 74, a first hit appears at x = 5374176 with bases (49, 25, −25, 49). If all four must be positive, add that constraint and continue. The same scan also reveals the clean example n = 24, k = 74, x = 300783360, which yields 158^4 + 59^4 = 134^4 + 133^4 with integer fourth roots across the board.
Why the tolerance is still needed
Even with a mathematically correct identity, floating-point evaluation of nested radicals and cube roots accumulates small error. That’s why comparing both sides with a tolerance is necessary. The integrality test on the bases—checking closeness to the nearest integer—separates exact arithmetic intent from numerical noise. The two conditions together remove false positives while retaining valid solutions.
Why this matters for searches of equal fourth powers
Equal sums of two fourth powers typically require exploring four integers. The structure here effectively moves the search into a three-parameter space (k, n, x), making brute-force exploration more approachable. However, the numerical implementation must be disciplined. Without checking the integrality of each base, most of the search time will be spent on near-equalities that do not represent perfect fourth powers. The added base checks and the tolerance gate significantly clean up the candidate set.
Closing thoughts
If you need to find integer triples (k, n, x) such that the derived four terms are perfect fourth powers and the identity holds, compute the bases explicitly, validate that each is integral within a strict threshold, and only then compare both sides with a small tolerance. If you require all four bases to be positive as well, add that condition. You can narrow or expand ranges, or lock n and k and scan x as shown above; the key is that the integrality checks and the tolerance work together to separate exact structural hits from floating-point lookalikes.
The article is based on a question from StackOverflow by Agbanwa Jamal and an answer by smallio.