Faulhaber's formula: Difference between revisions

Added Java
(Added D)
(Added Java)
Line 419:
2 Fcheck i.5
0 1 5 14 30</lang>
 
=={{header|Java}}==
{{trans|Kotlin}}
{{works with|Java|8}}
<lang Java>import java.util.Arrays;
import java.util.stream.IntStream;
 
public class FaulhabersFormula {
private static long gcd(long a, long b) {
if (b == 0) {
return a;
}
return gcd(b, a % b);
}
 
private static class Frac implements Comparable<Frac> {
private long num;
private long denom;
 
public static final Frac ZERO = new Frac(0, 1);
public static final Frac ONE = new Frac(1, 1);
 
public Frac(long n, long d) {
if (d == 0) throw new IllegalArgumentException("d must not be zero");
long nn = n;
long dd = d;
if (nn == 0) {
dd = 1;
} else if (dd < 0) {
nn = -nn;
dd = -dd;
}
long g = Math.abs(gcd(nn, dd));
if (g > 1) {
nn /= g;
dd /= g;
}
num = nn;
denom = dd;
}
 
public Frac plus(Frac rhs) {
return new Frac(num * rhs.denom + denom * rhs.num, rhs.denom * denom);
}
 
public Frac unaryMinus() {
return new Frac(-num, denom);
}
 
public Frac minus(Frac rhs) {
return this.plus(rhs.unaryMinus());
}
 
public Frac times(Frac rhs) {
return new Frac(this.num * rhs.num, this.denom * rhs.denom);
}
 
@Override
public int compareTo(Frac o) {
double diff = toDouble() - o.toDouble();
return Double.compare(diff, 0.0);
}
 
@Override
public boolean equals(Object obj) {
return null != obj && obj instanceof Frac && this.compareTo((Frac) obj) == 0;
}
 
@Override
public String toString() {
if (denom == 1) {
return Long.toString(num);
}
return String.format("%d/%d", num, denom);
}
 
private double toDouble() {
return (double) num / denom;
}
}
 
private static Frac bernoulli(int n) {
if (n < 0) throw new IllegalArgumentException("n may not be negative or zero");
Frac[] a = new Frac[n + 1];
Arrays.fill(a, Frac.ZERO);
for (int m = 0; m <= n; ++m) {
a[m] = new Frac(1, m + 1);
for (int j = m; j >= 1; --j) {
a[j - 1] = a[j - 1].minus(a[j]).times(new Frac(j, 1));
}
}
// returns 'first' Bernoulli number
if (n != 1) return a[0];
return a[0].unaryMinus();
}
 
private static int binomial(int n, int k) {
if (n < 0 || k < 0 || n < k) throw new IllegalArgumentException();
if (n == 0 || k == 0) return 1;
int num = IntStream.rangeClosed(k + 1, n).reduce(1, (a, b) -> a * b);
int den = IntStream.rangeClosed(2, n - k).reduce(1, (acc, i) -> acc * i);
return num / den;
}
 
private static void faulhaber(int p) {
System.out.printf("%d : ", p);
Frac q = new Frac(1, p + 1);
int sign = -1;
for (int j = 0; j <= p; ++j) {
sign *= -1;
Frac coeff = q.times(new Frac(sign, 1)).times(new Frac(binomial(p + 1, j), 1)).times(bernoulli(j));
if (Frac.ZERO.equals(coeff)) continue;
if (j == 0) {
if (!Frac.ONE.equals(coeff)) {
if (Frac.ONE.unaryMinus().equals(coeff)) {
System.out.print("-");
} else {
System.out.print(coeff);
}
}
} else {
if (Frac.ONE.equals(coeff)) {
System.out.print(" + ");
} else if (Frac.ONE.unaryMinus().equals(coeff)) {
System.out.print(" - ");
} else if (coeff.compareTo(Frac.ZERO) > 0) {
System.out.printf(" + %s", coeff);
} else {
System.out.printf(" - %s", coeff.unaryMinus());
}
}
int pwr = p + 1 - j;
if (pwr > 1)
System.out.printf("n^%d", pwr);
else
System.out.print("n");
}
System.out.println();
}
 
public static void main(String[] args) {
for (int i = 0; i <= 9; ++i) {
faulhaber(i);
}
}
}</lang>
{{out}}
<pre>0 : n
1 : 1/2n^2 + 1/2n
2 : 1/3n^3 + 1/2n^2 + 1/6n
3 : 1/4n^4 + 1/2n^3 + 1/4n^2
4 : 1/5n^5 + 1/2n^4 + 1/3n^3 - 1/30n
5 : 1/6n^6 + 1/2n^5 + 5/12n^4 - 1/12n^2
6 : 1/7n^7 + 1/2n^6 + 1/2n^5 - 1/6n^3 + 1/42n
7 : 1/8n^8 + 1/2n^7 + 7/12n^6 - 7/24n^4 + 1/12n^2
8 : 1/9n^9 + 1/2n^8 + 2/3n^7 - 7/15n^5 + 2/9n^3 - 1/30n
9 : 1/10n^10 + 1/2n^9 + 3/4n^8 - 7/10n^6 + 1/2n^4 - 3/20n^2</pre>
 
=={{header|Kotlin}}==
1,452

edits