Everything Java

← Back to blog

Published on Fri Jun 06 2025 12:00:00 GMT+0000 (Coordinated Universal Time) by Purusothaman Ramanujam

Google Guava Math Utilities: Mathematical Operations and Statistics

Introduction

Google Guava provides comprehensive mathematical utilities that extend Java’s basic math operations with advanced statistical functions, probability calculations, and mathematical operations. These utilities are particularly useful for data analysis, scientific computing, and statistical applications.

In this post, we’ll explore Guava’s math utilities and how they can enhance your mathematical computations.

Adding Guava to Your Project

Maven Dependency

<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.1.3-jre</version>
</dependency>

Gradle Dependency

implementation 'com.google.guava:guava:32.1.3-jre'

Statistics Utilities

IntMath

IntMath provides mathematical operations for integers with overflow checking:

import com.google.common.math.IntMath;
import java.math.RoundingMode;
public class IntMathExample {
public static void main(String[] args) {
// Basic arithmetic with overflow checking
int result = IntMath.checkedAdd(100, 200);
System.out.println("100 + 200 = " + result); // 300
// Multiplication with overflow checking
int product = IntMath.checkedMultiply(50, 60);
System.out.println("50 * 60 = " + product); // 3000
// Division with rounding
int quotient = IntMath.divide(10, 3, RoundingMode.UP);
System.out.println("10 / 3 (rounded up) = " + quotient); // 4
// Power calculation
int power = IntMath.pow(2, 10);
System.out.println("2^10 = " + power); // 1024
// Factorial
int factorial = IntMath.factorial(5);
System.out.println("5! = " + factorial); // 120
// Greatest common divisor
int gcd = IntMath.gcd(48, 18);
System.out.println("GCD(48, 18) = " + gcd); // 6
// Least common multiple
int lcm = IntMath.lcm(12, 18);
System.out.println("LCM(12, 18) = " + lcm); // 36
// Modulo with negative numbers
int mod = IntMath.mod(10, 3);
System.out.println("10 mod 3 = " + mod); // 1
int modNegative = IntMath.mod(-10, 3);
System.out.println("-10 mod 3 = " + modNegative); // 2
}
}

LongMath

LongMath provides similar operations for long integers:

import com.google.common.math.LongMath;
public class LongMathExample {
public static void main(String[] args) {
// Basic arithmetic with overflow checking
long result = LongMath.checkedAdd(1000000L, 2000000L);
System.out.println("1000000 + 2000000 = " + result);
// Multiplication with overflow checking
long product = LongMath.checkedMultiply(1000000L, 1000L);
System.out.println("1000000 * 1000 = " + product);
// Power calculation
long power = LongMath.pow(2L, 20);
System.out.println("2^20 = " + power); // 1048576
// Factorial (limited range)
long factorial = LongMath.factorial(10);
System.out.println("10! = " + factorial);
// Greatest common divisor
long gcd = LongMath.gcd(48L, 18L);
System.out.println("GCD(48, 18) = " + gcd); // 6
// Least common multiple
long lcm = LongMath.lcm(12L, 18L);
System.out.println("LCM(12, 18) = " + lcm); // 36
// Check if number is power of 2
boolean isPowerOf2 = LongMath.isPowerOfTwo(1024L);
System.out.println("1024 is power of 2: " + isPowerOf2); // true
// Log base 2
int log2 = LongMath.log2(1024L, RoundingMode.DOWN);
System.out.println("log2(1024) = " + log2); // 10
}
}

DoubleMath

DoubleMath provides utilities for double precision arithmetic:

import com.google.common.math.DoubleMath;
public class DoubleMathExample {
public static void main(String[] args) {
// Check if double is mathematical integer
boolean isInteger = DoubleMath.isMathematicalInteger(5.0);
System.out.println("5.0 is mathematical integer: " + isInteger); // true
boolean isNotInteger = DoubleMath.isMathematicalInteger(5.5);
System.out.println("5.5 is mathematical integer: " + isNotInteger); // false
// Round to integer
int rounded = DoubleMath.roundToInt(5.6, RoundingMode.UP);
System.out.println("5.6 rounded up = " + rounded); // 6
long roundedLong = DoubleMath.roundToLong(123456.789, RoundingMode.DOWN);
System.out.println("123456.789 rounded down = " + roundedLong); // 123456
// Check if double is finite
boolean isFinite = DoubleMath.isFinite(5.0);
System.out.println("5.0 is finite: " + isFinite); // true
boolean isInfinite = DoubleMath.isFinite(Double.POSITIVE_INFINITY);
System.out.println("Infinity is finite: " + isInfinite); // false
// Factorial for doubles
double factorial = DoubleMath.factorial(5);
System.out.println("5! = " + factorial); // 120.0
// Log base 2
double log2 = DoubleMath.log2(1024.0);
System.out.println("log2(1024) = " + log2); // 10.0
}
}

BigIntegerMath

BigIntegerMath provides utilities for BigInteger arithmetic:

import com.google.common.math.BigIntegerMath;
import java.math.BigInteger;
public class BigIntegerMathExample {
public static void main(String[] args) {
// Factorial for large numbers
BigInteger factorial = BigIntegerMath.factorial(100);
System.out.println("100! has " + factorial.toString().length() + " digits");
// Power calculation
BigInteger power = BigIntegerMath.pow(BigInteger.valueOf(2), 100);
System.out.println("2^100 = " + power);
// Square root
BigInteger sqrt = BigIntegerMath.sqrt(BigInteger.valueOf(100), RoundingMode.DOWN);
System.out.println("sqrt(100) = " + sqrt); // 10
// Greatest common divisor
BigInteger gcd = BigIntegerMath.gcd(
BigInteger.valueOf(48),
BigInteger.valueOf(18)
);
System.out.println("GCD(48, 18) = " + gcd); // 6
// Check if number is power of 2
boolean isPowerOf2 = BigIntegerMath.isPowerOfTwo(BigInteger.valueOf(1024));
System.out.println("1024 is power of 2: " + isPowerOf2); // true
// Log base 2
int log2 = BigIntegerMath.log2(BigInteger.valueOf(1024), RoundingMode.DOWN);
System.out.println("log2(1024) = " + log2); // 10
}
}

Statistics and Probability

Stats

Guava provides statistical utilities for data analysis:

import com.google.common.math.Stats;
import com.google.common.math.DoubleMath;
public class StatisticsExample {
public static void main(String[] args) {
// Create stats from values
Stats stats = Stats.of(1.0, 2.0, 3.0, 4.0, 5.0);
System.out.println("Count: " + stats.count()); // 5
System.out.println("Mean: " + stats.mean()); // 3.0
System.out.println("Sum: " + stats.sum()); // 15.0
System.out.println("Population variance: " + stats.populationVariance()); // 2.0
System.out.println("Population standard deviation: " + stats.populationStandardDeviation()); // 1.414...
System.out.println("Sample variance: " + stats.sampleVariance()); // 2.5
System.out.println("Sample standard deviation: " + stats.sampleStandardDeviation()); // 1.581...
System.out.println("Min: " + stats.min()); // 1.0
System.out.println("Max: " + stats.max()); // 5.0
// Accumulate stats
Stats.Accumulator accumulator = Stats.accumulator();
accumulator.add(1.0);
accumulator.add(2.0);
accumulator.add(3.0);
Stats accumulatedStats = accumulator.snapshot();
System.out.println("Accumulated mean: " + accumulatedStats.mean()); // 2.0
}
}

Quantiles

Calculate quantiles and percentiles:

import com.google.common.math.Quantiles;
public class QuantilesExample {
public static void main(String[] args) {
// Calculate median (50th percentile)
double median = Quantiles.median().compute(1.0, 2.0, 3.0, 4.0, 5.0);
System.out.println("Median: " + median); // 3.0
// Calculate 25th percentile (Q1)
double q1 = Quantiles.percentiles().index(25).compute(1.0, 2.0, 3.0, 4.0, 5.0);
System.out.println("Q1 (25th percentile): " + q1); // 2.0
// Calculate 75th percentile (Q3)
double q3 = Quantiles.percentiles().index(75).compute(1.0, 2.0, 3.0, 4.0, 5.0);
System.out.println("Q3 (75th percentile): " + q3); // 4.0
// Calculate multiple percentiles at once
Map<Integer, Double> percentiles = Quantiles.percentiles()
.indexes(25, 50, 75)
.compute(1.0, 2.0, 3.0, 4.0, 5.0);
System.out.println("Percentiles: " + percentiles);
// {25=2.0, 50=3.0, 75=4.0}
}
}

Mathematical Constants

Guava provides mathematical constants:

import com.google.common.math.DoubleMath;
public class MathematicalConstantsExample {
public static void main(String[] args) {
// Mathematical constants
System.out.println("PI: " + Math.PI);
System.out.println("E: " + Math.E);
// Check if double is mathematical integer
System.out.println("5.0 is integer: " + DoubleMath.isMathematicalInteger(5.0)); // true
System.out.println("5.5 is integer: " + DoubleMath.isMathematicalInteger(5.5)); // false
// Check if double is finite
System.out.println("5.0 is finite: " + DoubleMath.isFinite(5.0)); // true
System.out.println("Infinity is finite: " + DoubleMath.isFinite(Double.POSITIVE_INFINITY)); // false
}
}

Practical Examples

Statistical Analysis

public class StatisticalAnalysisExample {
public static class DataAnalyzer {
private final Stats stats;
public DataAnalyzer(double... values) {
this.stats = Stats.of(values);
}
public void printSummary() {
System.out.println("Data Summary:");
System.out.println(" Count: " + stats.count());
System.out.println(" Mean: " + stats.mean());
System.out.println(" Standard Deviation: " + stats.sampleStandardDeviation());
System.out.println(" Min: " + stats.min());
System.out.println(" Max: " + stats.max());
System.out.println(" Range: " + (stats.max() - stats.min()));
}
public boolean isOutlier(double value, double threshold) {
double zScore = Math.abs((value - stats.mean()) / stats.sampleStandardDeviation());
return zScore > threshold;
}
}
public static void main(String[] args) {
double[] data = {1.0, 2.0, 3.0, 4.0, 5.0, 100.0}; // 100 is an outlier
DataAnalyzer analyzer = new DataAnalyzer(data);
analyzer.printSummary();
// Check for outliers
for (double value : data) {
if (analyzer.isOutlier(value, 2.0)) {
System.out.println(value + " is an outlier");
}
}
}
}

Mathematical Operations

public class MathematicalOperationsExample {
public static class MathUtils {
public static int safeAdd(int a, int b) {
return IntMath.checkedAdd(a, b);
}
public static int safeMultiply(int a, int b) {
return IntMath.checkedMultiply(a, b);
}
public static int gcd(int a, int b) {
return IntMath.gcd(a, b);
}
public static int lcm(int a, int b) {
return IntMath.lcm(a, b);
}
public static boolean isPowerOfTwo(int n) {
return IntMath.isPowerOfTwo(n);
}
public static int factorial(int n) {
return IntMath.factorial(n);
}
}
public static void main(String[] args) {
System.out.println("Safe addition: " + MathUtils.safeAdd(1000, 2000));
System.out.println("Safe multiplication: " + MathUtils.safeMultiply(50, 60));
System.out.println("GCD(48, 18): " + MathUtils.gcd(48, 18));
System.out.println("LCM(12, 18): " + MathUtils.lcm(12, 18));
System.out.println("Is 1024 power of 2: " + MathUtils.isPowerOfTwo(1024));
System.out.println("5! = " + MathUtils.factorial(5));
}
}

Best Practices

  1. Use Checked Operations: Use checked arithmetic operations to prevent overflow
  2. Choose Appropriate Precision: Use IntMath for integers, LongMath for longs, DoubleMath for doubles
  3. Handle Rounding: Specify rounding mode for division operations
  4. Use Stats for Data Analysis: Use Stats class for statistical calculations
  5. Validate Inputs: Check for valid inputs before mathematical operations

Common Pitfalls

  1. Overflow: Not using checked operations for large numbers
  2. Precision Loss: Using integer math where floating-point is needed
  3. Rounding Errors: Not specifying rounding mode for division
  4. Invalid Inputs: Not validating inputs for mathematical operations
  5. Performance: Using BigInteger for small numbers

Performance Considerations

  1. Checked Operations: Slightly slower but safer than unchecked operations
  2. BigInteger Operations: More expensive than primitive operations
  3. Statistical Calculations: Stats class is optimized for performance
  4. Memory Usage: BigInteger operations use more memory
  5. Caching: Consider caching expensive mathematical calculations

Conclusion

Guava’s math utilities provide comprehensive mathematical operations with safety features like overflow checking and proper rounding. These utilities are essential for scientific computing, data analysis, and any application requiring precise mathematical operations.

Use the appropriate math utility class based on your data type and requirements. Always use checked operations when dealing with user input or potentially large numbers to prevent overflow errors.

The statistical utilities are particularly useful for data analysis and can help you understand your data better through descriptive statistics and outlier detection.

Resources

Written by Purusothaman Ramanujam

← Back to blog