Das war – Dänisch!
Das heutige Rätsel passt zu der aktuellen Folge von Tool Talk über Disassembler. Und zwar habe ich einmal ein kleines Programm („10000.java“) geschrieben, das ich danach erst übersetzt und dann mittels javap disassembliert habe. Aber was macht es? Genau dies gilt es herauszufinden!
Tipp: Eigentlich ist das Rätsel schon gelöst, wenn du einen Weg findest, wie man mit diesem Problem umgehen kann.
public class 10000 {
public 10000();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc2_w #7 // long 13591409l
3: invokestatic #9 // Method
// java/math/BigInteger.valueOf:(J)Ljava/math/BigInteger;
6: astore_1
7: ldc2_w #15 // long 545140134l
10: invokestatic #9 // Method
// java/math/BigInteger.valueOf:(J)Ljava/math/BigInteger;
13: astore_2
14: ldc2_w #17 // long 640320l
17: invokestatic #9 // Method
// java/math/BigInteger.valueOf:(J)Ljava/math/BigInteger;
20: astore_3
21: aload_3
22: iconst_3
23: invokevirtual #19 // Method
// java/math/BigInteger.pow:(I)Ljava/math/BigInteger;
26: astore 4
28: getstatic #23 // Field
// java/math/BigInteger.ZERO:Ljava/math/BigInteger;
31: astore 5
33: getstatic #27 // Field
// java/math/BigInteger.ONE:Ljava/math/BigInteger;
36: astore 6
38: getstatic #27 // Field
// java/math/BigInteger.ONE:Ljava/math/BigInteger;
41: astore 7
43: getstatic #27 // Field
// java/math/BigInteger.ONE:Ljava/math/BigInteger;
46: astore 8
48: getstatic #27 // Field
// java/math/BigInteger.ONE:Ljava/math/BigInteger;
51: astore 9
53: iconst_0
54: istore 10
56: iload 10
58: sipush 720
61: if_icmpge 250
64: iload 10
66: iconst_2
67: irem
68: ifne 77
71: getstatic #27 // Field
// java/math/BigInteger.ONE:Ljava/math/BigInteger;
74: goto 83
77: getstatic #27 // Field
// java/math/BigInteger.ONE:Ljava/math/BigInteger;
80: invokevirtual #30 // Method
// java/math/BigInteger.negate:()Ljava/math/BigInteger;
83: astore 11
85: iload 10
87: ifle 177
90: bipush 6
92: iload 10
94: imul
95: iconst_5
96: isub
97: istore 12
99: iload 12
101: bipush 6
103: iload 10
105: imul
106: if_icmpgt 128
109: aload 6
111: iload 12
113: i2l
114: invokestatic #9 // Method
// java/math/BigInteger.valueOf:(J)Ljava/math/BigInteger;
117: invokevirtual #34 // Method
// java/math/BigInteger.multiply:(Ljava/math/BigInteger;)Ljava/math/BigInteger;
120: astore 6
122: iinc 12, 1
125: goto 99
128: iconst_3
129: iload 10
131: imul
132: iconst_2
133: isub
134: istore 12
136: iload 12
138: iconst_3
139: iload 10
141: imul
142: if_icmpgt 164
145: aload 7
147: iload 12
149: i2l
150: invokestatic #9 // Method
// java/math/BigInteger.valueOf:(J)Ljava/math/BigInteger;
153: invokevirtual #34 // Method java/math/BigInteger.multiply:(Ljava/math/BigInteger;)Ljava/math/BigInteger;
156: astore 7
158: iinc 12, 1
161: goto 136
164: aload 8
166: iload 10
168: i2l
169: invokestatic #9 // Method
// java/math/BigInteger.valueOf:(J)Ljava/math/BigInteger;
172: invokevirtual #34 // Method
// java/math/BigInteger.multiply:(Ljava/math/BigInteger;)Ljava/math/BigInteger;
175: astore 8
177: aload 11
179: aload 6
181: invokevirtual #34 // Method
// java/math/BigInteger.multiply:(Ljava/math/BigInteger;)Ljava/math/BigInteger;
184: aload_1
185: aload_2
186: iload 10
188: i2l
189: invokestatic #9 // Method
// java/math/BigInteger.valueOf:(J)Ljava/math/BigInteger;
192: invokevirtual #34 // Method
// java/math/BigInteger.multiply:(Ljava/math/BigInteger;)Ljava/math/BigInteger;
195: invokevirtual #38 // Method
// java/math/BigInteger.add:(Ljava/math/BigInteger;)Ljava/math/BigInteger;
198: invokevirtual #34 // Method
// java/math/BigInteger.multiply:(Ljava/math/BigInteger;)Ljava/math/BigInteger;
201: astore 12
203: aload 7
205: aload 8
207: iconst_3
208: invokevirtual #19 // Method
// java/math/BigInteger.pow:(I)Ljava/math/BigInteger;
211: invokevirtual #34 // Method java/math/BigInteger.multiply:(Ljava/math/BigInteger;)Ljava/math/BigInteger;
214: aload 9
216: invokevirtual #34 // Method
// java/math/BigInteger.multiply:(Ljava/math/BigInteger;)Ljava/math/BigInteger;
219: astore 13
221: aload 5
223: aload 12
225: aload 13
227: invokevirtual #41 // Method
// java/math/BigInteger.divide:(Ljava/math/BigInteger;)Ljava/math/BigInteger;
230: invokevirtual #38 // Method
// java/math/BigInteger.add:(Ljava/math/BigInteger;)Ljava/math/BigInteger;
233: astore 5
235: aload 9
237: aload 4
239: invokevirtual #34 // Method
// java/math/BigInteger.multiply:(Ljava/math/BigInteger;)Ljava/math/BigInteger;
242: astore 9
244: iinc 10, 1
247: goto 56
250: new #44 // class java/math/BigDecimal
253: dup
254: aload_3
255: invokespecial #46 // Method
// java/math/BigDecimal."<init>":(Ljava/math/BigInteger;)V
258: astore 10
260: new #44 // class java/math/BigDecimal
263: dup
264: aload_3
265: invokevirtual #49 // Method
// java/math/BigInteger.doubleValue:()D
268: invokestatic #53 // Method java/lang/Math.sqrt:(D)D
271: invokespecial #59 // Method java/math/BigDecimal."<init>":(D)V
274: astore 11
276: ldc2_w #62 // long 2l
279: invokestatic #64 // Method
// java/math/BigDecimal.valueOf:(J)Ljava/math/BigDecimal;
282: astore 12
284: iconst_0
285: istore 13
287: iload 13
289: bipush 100
291: if_icmpge 325
294: aload 11
296: aload 10
298: aload 11
300: getstatic #67 // Field
// java/math/MathContext.DECIMAL128:Ljava/math/MathContext;
303: invokevirtual #73 // Method
/ java/math/BigDecimal.divide:(Ljava/math/BigDecimal;Ljava/math/MathContext;)Ljava/math/BigDecimal;
306: invokevirtual #76 // Method
// java/math/BigDecimal.add:(Ljava/math/BigDecimal;)Ljava/math/BigDecimal;
309: aload 12
311: getstatic #67 // Field
// java/math/MathContext.DECIMAL128:Ljava/math/MathContext;
314: invokevirtual #73 // Method
// java/math/BigDecimal.divide:(Ljava/math/BigDecimal;Ljava/math/MathContext;)Ljava/math/BigDecimal;
317: astore 11
319: iinc 13, 1
322: goto 287
325: aload 10
327: aload 11
329: invokevirtual #79 // Method
// java/math/BigDecimal.multiply:(Ljava/math/BigDecimal;)Ljava/math/BigDecimal;
332: ldc2_w #81 // long 12l
335: invokestatic #64 // Method
// java/math/BigDecimal.valueOf:(J)Ljava/math/BigDecimal;
338: new #44 // class java/math/BigDecimal
341: dup
342: aload 5
344: invokespecial #46 // Method
// java/math/BigDecimal."<init>":(Ljava/math/BigInteger;)V
347: invokevirtual #79 // Method
// java/math/BigDecimal.multiply:(Ljava/math/BigDecimal;)Ljava/math/BigDecimal;
350: new #68 // class java/math/MathContext
353: dup
354: sipush 10002
357: getstatic #83 // Field
// java/math/RoundingMode.HALF_UP:Ljava/math/RoundingMode;
360: invokespecial #89 // Method
// java/math/MathContext."<init>":(ILjava/math/RoundingMode;)V
363: invokevirtual #73 // Method
// java/math/BigDecimal.divide:(Ljava/math/BigDecimal;Ljava/math/MathContext;)Ljava/math/BigDecimal;
366: astore 13
368: aload 13
370: new #68 // class java/math/MathContext
373: dup
374: sipush 10000
377: getstatic #83 // Field
// java/math/RoundingMode.HALF_UP:Ljava/math/RoundingMode;
380: invokespecial #89 // Method
// java/math/MathContext."<init>":(ILjava/math/RoundingMode;)V
383: invokevirtual #92 // Method
// java/math/BigDecimal.round:(Ljava/math/MathContext;)Ljava/math/BigDecimal;
386: astore 13
388: aload 13
390: invokevirtual #96 // Method
// java/math/BigDecimal.toPlainString:()Ljava/lang/String;
393: astore 14
395: getstatic #100 // Field java/lang/System.out:Ljava/io/PrintStream;
398: aload 14
400: invokevirtual #106 // Method
// java/io/PrintStream.println:(Ljava/lang/String;)V
403: return
}
Lösung zum Rätsel „Taler du assembler?“
Lösung: Die disassemblierte Java-Klasse („10000.java“) berechnet die Kreiszahl π (Pi) – mittels der Chudnovsky-Formel. Aber wie kommt man darauf? Nun – ich habe einfach mein lokal laufendes LLM (Qwen3-Coder-Next) gefragt, siehe Abbildung 1!

So einfach geht das mit KI!
Hier das Originalprogramm (das ich im Übrigen auch mittels KI erstellt habe):
import java.math.*;
public class Pi10000 {
public static void main(String[] args) {
final int NUM_DIGITS = 10_000;
// Chudnovsky: ca. 14 Dezimalstellen pro Term ->
// für 10.000 Stellen braucht man ~715 Terme
final int TERMS = 720; // etwas Puffer
// Konstanten aus der Chudnovsky-Formel
final BigInteger A = BigInteger.valueOf(13591409);
final BigInteger B = BigInteger.valueOf(545140134);
final BigInteger D = BigInteger.valueOf(640320);
final BigInteger D3 = D.pow(3); // = 640320³
// Summe als BigInteger: Σ term_k = S
// term_k = [(-1)^k * (6k)! * (A + B·k)] / [(3k)! * (k!)^3 * D3^k]
BigInteger sum = BigInteger.ZERO;
BigInteger fact6k = BigInteger.ONE; // (6k)!
BigInteger fact3k = BigInteger.ONE; // (3k)!
BigInteger factk = BigInteger.ONE; // k!
BigInteger d3pow = BigInteger.ONE; // D3^k
for (int k = 0; k < TERMS; k++) {
// (-1)^k
BigInteger sign = (k % 2 == 0) ? BigInteger.ONE : BigInteger.ONE.negate();
// Fakultäten aktualisieren (nur für k > 0)
if (k > 0) {
// (6k)! = (6(k-1))! × (6k−5) × (6k−4) × … × (6k)
for (int i = 6 * k - 5; i <= 6 * k; i++) {
fact6k = fact6k.multiply(BigInteger.valueOf(i));
}
// (3k)! = (3(k-1))! × (3k−2) × (3k−1) × (3k)
for (int i = 3 * k - 2; i <= 3 * k; i++) {
fact3k = fact3k.multiply(BigInteger.valueOf(i));
}
// k! = (k−1)! × k
factk = factk.multiply(BigInteger.valueOf(k));
}
// Zähler: sign × (6k)! × (A + B·k)
BigInteger numerator = sign
.multiply(fact6k)
.multiply(A.add(B.multiply(BigInteger.valueOf(k))));
// Nenner: (3k)! × (k!)^3 × D3^k
BigInteger denominator = fact3k
.multiply(factk.pow(3))
.multiply(d3pow);
// Addiere term_k = numerator / denominator zur Summe
sum = sum.add(numerator.divide(denominator));
// D3^k für nächsten Term aktualisieren
d3pow = d3pow.multiply(D3);
}
// Pi ≈ sqrt(D³) / (12 · sum), wobei sqrt(D³) = D · sqrt(D)
// Also: pi = D · sqrt(D) / (12 · sum)
// 1. sqrt(D) berechnen mit Newton-Iteration (für Java 8+)
BigDecimal D_BD = new BigDecimal(D);
BigDecimal sqrtD = new BigDecimal(Math.sqrt(D.doubleValue())); // Startwert
BigDecimal TWO = BigDecimal.valueOf(2);
// 100 Iterationen → mehr als genug für 10.000 Stellen (da D klein ist)
for (int i = 0; i < 100; i++) {
sqrtD = sqrtD.add(D_BD.divide(sqrtD, MathContext.DECIMAL128))
.divide(TWO, MathContext.DECIMAL128);
}
// 2. Pi berechnen
// pi = (D · sqrt(D)) / (12 · sum)
BigDecimal pi = D_BD.multiply(sqrtD)
.divide(BigDecimal.valueOf(12).multiply(new BigDecimal(sum)),
new MathContext(NUM_DIGITS + 2, RoundingMode.HALF_UP));
// 3. Auf NUM_DIGITS runden
pi = pi.round(new MathContext(NUM_DIGITS, RoundingMode.HALF_UP));
// 4. Ausgabe
String piStr = pi.toPlainString();
System.out.println(piStr);
// Optional: Prüfung auf Länge (sollte 10001 Zeichen sein:
// "3." + 10.000 Stellen)
// System.out.println("\nLänge: " + (piStr.length() - 1) +
// " Dezimalstellen");
}
}