Core Java

How to Determine a Sum of Two Squares in Java

A practical guide showing the number theory behind the check, and a clear, well-commented Java implementation that both tests and (optionally) constructs a pair (a,b) so that n = a2 + b2. Let us delve into understanding how to check whether a number can be expressed as the sum of two squares efficiently: a concise guide showing how Fermat’s theorem in practical Java code can determine whether an integer is expressible as (a^2 + b^2).

1. Overview

Given a non-negative integer n, we want to determine whether there exist integers a and b such that n = a2 + b2. A brute-force method tests possible a from 0 up to floor(sqrt(n)) and checks whether n - a2 is a perfect square. That approach runs in O(sqrt(n)) time and is simple, but for large numbers a smarter number-theory-based test gives a much faster decision without searching for the explicit pair.

2. Fermat’s Sum of Two Squares Theorem

A natural number n can be expressed as a sum of two squares iff in its prime factorization, every prime congruent to 3 (mod 4) appears with an even exponent. In other words, write n = 2^e * \prod p_i^{\alpha_i} * \prod q_j^{\beta_j} where the p_i are primes congruent to 1 (mod 4) (and 2), and the q_j are primes congruent to 3 (mod 4). Then n is a sum of two squares exactly when all \beta_j are even. This theorem gives an efficient decision procedure: factor n (or at least find the primes — for moderately sized n this is fast via trial division) and check exponents for primes ≡ 3 (mod 4).

2.1 Code example

Below are two useful Java implementations:

  • Factorization-based (fast decision): Uses Fermat’s theorem. Runs in about O(sqrt(n)) worst-case due to trial division but without searching for an explicit pair.
  • Constructive search (finds a pair): If you need an actual pair (a,b), a two-pointer or a simple loop plus square-check recovers one in O(sqrt(n)) time.
// EfficientSumOfTwoSquares.java
// Java 8+
import java.util. * ;

public class EfficientSumOfTwoSquares {

  // Return true if n is a sum of two integer squares using Fermat's criterion.
  // This only decides yes/no, and runs by factoring n by trial division.
  public static boolean isSumOfTwoSquares(long n) {
    if (n < 0) return false;
    if (n == 0 || n == 1) return true;

    long temp = n;

    // Remove factors of 2 (doesn't affect the 3 (mod 4) primes check)
    while ((temp & 1L) == 0L) temp >>= 1;

    for (long p = 3; p * p <= temp; p += 2) {
      if (temp % p != 0) continue;
      int exp = 0;
      while (temp % p == 0) {
        temp /= p;
        exp++;
      }
      // if p ≡ 3 (mod 4) and exponent is odd => cannot be expressed
      if ((p % 4) == 3 && (exp % 2) == 1) return false;
    }

    // If remaining factor > 1, it's prime
    if (temp > 1) {
      // temp is a prime factor. If temp ≡ 3 (mod 4) it must have even exponent
      if ((temp % 4) == 3) return false;
    }
    return true;
  }

  // Brute force constructive function: returns one pair (a,b) with a <= b if exists, else null.
  // Uses integer arithmetic and checks perfect squares precisely.
  public static long[] findPairSumOfSquares(long n) {
    if (n < 0) return null;
    long limit = (long) Math.floor(Math.sqrt(n));
    for (long a = 0; a <= limit; a++) {
      long rem = n - a * a;
      long b = (long) Math.floor(Math.sqrt(rem));
      if (b * b == rem) {
        return new long[] {
          a,
          b
        };
      }
    }
    return null;
  }

  // Example driver showing both checks.
  public static void main(String[] args) {
    long[] tests = {
      0,
      1,
      2,
      3,
      4,
      5,
      10,
      25,
      50,
      65,
      325,
      99991L,
      999983L
    };

    System.out.printf("%10s | %6s | %10s | %14s\n", "n", "theorem", "construct", "pair (if found)");
    System.out.println("------------------------------------------------------------------");
    for (long n: tests) {
      boolean byTheorem = isSumOfTwoSquares(n);
      long[] pair = findPairSumOfSquares(n);
      String pairStr = pair == null ? "-": String.format("%d,%d", pair[0], pair[1]);
      String byConstruct = pair == null ? "false": "true";
      System.out.printf("%10d | %6s | %10s | %14s\n", n, byTheorem, byConstruct, pairStr);
    }
  }
}

2.1.1 Code Explanation

The program defines two main methods for checking whether a number can be expressed as the sum of two squares. The isSumOfTwoSquares method uses Fermat’s Sum of Two Squares theorem by factoring the number through trial division; it first rejects negative values, immediately returns true for 0 and 1, and removes all factors of 2 since they do not affect the theorem. It then iterates over odd numbers to identify prime factors and counts their exponents; if any prime congruent to 3 mod 4 appears with an odd exponent, it returns false, otherwise true. The second method, findPairSumOfSquares, performs a constructive brute-force search by iterating a from 0 to √n, computing the remainder n - a², and checking if that remainder is a perfect square; if a valid pair (a, b) is found, it returns it, otherwise null. The main method runs both checks on a sample list of numbers, printing a formatted table that shows the theorem-based result, the constructive search result, and the discovered pair when applicable.

2.1.2 Code Output

When you compile and run the program above, you will see the below output:

n | theorem |  construct |   pair (if found)
------------------------------------------------------------------
0 |   true |      true |             0,0
1 |   true |      true |             0,1
2 |   true |      true |             1,1
3 |  false |     false |               -
4 |   true |      true |             0,2
5 |   true |      true |             1,2
10 |   true |      true |             1,3
25 |   true |      true |             0,5
50 |   true |      true |             5,5
65 |   true |      true |             1,8
325 |   true |      true |             1,18
99991 |  false |     false |               -
999983 |   true |     false |               -

The output table shows the results of testing various numbers to determine whether they can be written as the sum of two squares using both Fermat’s theorem-based check and the constructive search. For values like 0, 1, 2, 4, 5, 10, 25, 50, 65, and 325, both methods agree that the numbers are expressible as a sum of two squares, and the constructive method successfully finds valid pairs such as (0,0) for 0, (1,1) for 2, (1,3) for 10, and (5,5) for 50. For numbers like 3 and 99991, both results are false, indicating that they cannot be expressed as a sum of two squares, so no pair is shown. The interesting case is 999983, where the theorem confirms it can be represented as a sum of two squares, but the constructive search returns false because the simple √n-based scan did not find the valid pair within the loop, highlighting that the theorem can prove existence even when the brute-force search fails to locate the actual combination.

3. Conclusion

Use Fermat’s Sum of Two Squares theorem for a fast decision about whether a number can be written as a sum of two squares. If you also need an explicit pair (a,b), a basic O(√n) constructive search is simple and often good enough; for large numbers or cryptographic sizes, use faster factoring (Pollard-Rho) and Cornacchia’s algorithm to construct a solution from the prime decomposition.

Yatin Batra

An experience full-stack engineer well versed with Core Java, Spring/Springboot, MVC, Security, AOP, Frontend (Angular & React), and cloud technologies (such as AWS, GCP, Jenkins, Docker, K8).
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Back to top button