Skip to content

Instantly share code, notes, and snippets.

@coderodde
Last active July 13, 2025 09:35
Show Gist options
  • Save coderodde/47e308e403a52ffccb179c03c70fae61 to your computer and use it in GitHub Desktop.
Save coderodde/47e308e403a52ffccb179c03c70fae61 to your computer and use it in GitHub Desktop.
A small Java program for computing volumes of n-dimensional balls.
package io.github.coderodde.math.simulation.volumes;
public class NdimensionalBallVolumes {
private static final int LARGEST_DIMENSION = 50;
public static void main(String[] args) {
final Volume[] volumes = generateVolumes(LARGEST_DIMENSION);
final int maxVolumeExpressionLength =
getMaximumVolumeExpressionLength(volumes);
final int maxVolumeAliasLength =
Integer.toString(volumes.length).length();
final String lineFormat =
String.format("V_{%%%dd} &= %%-%ds \\\\ %%%% n = %%%dd\n",
maxVolumeAliasLength,
maxVolumeExpressionLength,
maxVolumeAliasLength);
System.out.println("$$");
System.out.println("\\begin{aligned}");
for (int n = 0; n <= LARGEST_DIMENSION; ++n) {
System.out.printf(lineFormat,
n,
volumes[n],
n);
}
System.out.println("\\end{aligned}");
System.out.println("$$");
}
private static int getMaximumVolumeExpressionLength(
final Volume[] volumes) {
int maxLength = -1;
for (final Volume volume : volumes) {
maxLength = Math.max(maxLength, volume.toString().length());
}
return maxLength;
}
private static Volume[] generateVolumes(final int n) {
final Volume[] volumes = new Volume[n + 1];
for (int i = 0; i <= n; ++i) {
volumes[i] = new Volume(i);
}
return volumes;
}
}
package io.github.coderodde.math.simulation.volumes;
import java.math.BigInteger;
/**
*
* @version 1.0.0 (Jul 10, 2025)
* @since 1.0.0 (Jul 10, 2025)
*/
public class Volume {
protected BigInteger numerator;
protected BigInteger denominator;
protected int piExponent;
protected final int dimension;
public Volume(final int dimension) {
this.dimension = checkDimension(dimension);
this.piExponent = dimension / 2;
this.numerator = BigInteger.ONE;
this.denominator = BigInteger.ONE;
if (dimension % 2 == 0) {
for (int k = 1; k <= dimension / 2; ++k) {
this.denominator =
this.denominator.multiply(BigInteger.valueOf(k));
}
} else {
for (int k = 1; k <= dimension; k += 2) {
this.numerator = this.numerator.multiply(BigInteger.valueOf(2));
this.denominator =
this.denominator.multiply(BigInteger.valueOf(k));
}
}
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
if (denominator.equals(BigInteger.ONE)) {
appendNumeratorString(sb);
} else {
sb.append("\\frac{");
appendNumeratorString(sb);
sb.append("}{")
.append(denominator)
.append("}");
}
return sb.toString();
}
private void appendNumeratorString(final StringBuilder sb) {
if (dimension == 0) {
sb.append("0");
return;
}
if (numerator.compareTo(BigInteger.ONE) > 0) {
sb.append(numerator)
.append(" ");
}
if (piExponent > 0) {
sb.append("\\pi");
if (piExponent > 1) {
sb.append("^{")
.append(piExponent)
.append("}");
}
sb.append(" ");
}
if (dimension > 0) {
sb.append("R");
if (dimension > 1) {
sb.append("^{")
.append(dimension)
.append("}");
}
}
}
private static int checkDimension(final int dimension) {
if (dimension < 0) {
final String exceptionMessage = String.format("dimension(%d) < 0",
dimension);
throw new IllegalArgumentException(exceptionMessage);
}
return dimension;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment