Das Wissensportal für IT-Professionals. Entdecke die Tiefe und Breite unseres IT-Contents in exklusiven Themenchannels und Magazinmarken.

heise conferences gmbh

(vormals SIGS DATACOM GmbH)

Lindlaustraße 2c, 53842 Troisdorf

Tel: +49 (0)511/5352-100

service-sigs@heise.de

Taler du assembler?

Author Image
Thomas Ronzon

Teamleiter und Senior Softwareentwickler


  • 20.05.2026
  • Lesezeit: 22 Minuten
  • 44 Views

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!

Code Lösung zu Artikel:  Taler du assembler?

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");

}

}

. . .

Author Image

Thomas Ronzon

Teamleiter und Senior Softwareentwickler
Zu Inhalten

Thomas Ronzon arbeitet als Teamleiter und Senior Softwareentwickler bei der w3logistics AG in Dortmund. Dabei beschäftigt er sich vor allem mit der Modernisierung von unternehmenskritischen Logistikanwendungen. Darüber hinaus veröffentlicht Thomas Ronzon regelmäßig Fachartikel.


Artikel teilen