Delphi-PRAXiS
Seite 3 von 4     123 4      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Genauigkeit von String to Single Konvertierung (https://www.delphipraxis.net/203853-genauigkeit-von-string-single-konvertierung.html)

himitsu 5. Apr 2020 10:44

AW: Genauigkeit von String to Single Konvertierung
 
Es gibt auch noch was von negaH, das sauschnell ist. (DECMath, Hagen Reddmann)
Ich weiß grade nicht wie es dort aussieht, aber da wollte sich auch jemand aus der DP darum kümmern den Code auch für neuere Delphis zur Verfügung zu stellen (da damals nur als DCU verfügbar war)

Zitat:

typischerweise Finanzen, Kryptographie und Tschenrechner
in Bezug auf Finanzen reichen die Festkommatypen (ala Currency) meistens aus,
so lange Einem die hunderstel Cent (4 Nachkommastellen) und einige 100 Billion Euro ausreichen.

und der Kryptographie nimmt man zwar große Zahlen, aber dort fast ausschließelich Ganzzahlige sehr große,
das geht dann auch in die Richtung, wie ein 32 Bit-Delphi mit 64 Bit umgeht,
wo also "eine" Zahl aus zwei oder mehr Integern zusammengesetzt ist.

himitsu 5. Apr 2020 11:00

AW: Genauigkeit von String to Single Konvertierung
 
[deleted]

Andreas13 5. Apr 2020 15:49

AW: Genauigkeit von String to Single Konvertierung
 
Zitat:

Zitat von himitsu (Beitrag 1461305)
Zitat:

typischerweise Finanzen, Kryptographie und Tschenrechner
in Bezug auf Finanzen reichen die Festkommatypen (ala Currency) meistens aus,
so lange Einem die hunderstel Cent (4 Nachkommastellen) und einige 100 Billion Euro ausreichen.

Das stimmt nicht ganz: Rundungsfehler durch die binäre Zahlenkodierung, die begrenzte Wortlänge des Prozessors etc. lauern auf uns fast überall. Hier habe ich ein anschauliches kaufmännisches Beispiel (= recht einfache Berechnungen) aus dem Buch: Muller + Brisebarre + de Dinechin et al.: Handbook of Floating-Point Arithmetic. Boston: Birkhäuser, 2010, (ISBN 978-0-8176-4 704-9) S. 10 - 11:

Das Angebot der "Chaotic Bank Society":
Sie zahlen zunächst e - 1 $ auf Ihr Konto ein, wobei e = 2. 7182818… ist die Basis der natürlichen Logarithmen. Im ersten Jahr nehmen wir 1 $ von Ihrem Konto als Bearbeitungsgebühren. Das zweite Jahr ist besser für Sie: Wir multiplizieren Ihr Kapital mit 2, und wir nehmen 1 $ Bearbeitungsgebühren von Ihrem Konto. Das dritte Jahr ist sogar noch besser: Wir vervielfachen Ihr Kapital durch 3, und wir nehmen immer nur noch 1 $ an Bearbeitungsgebühren. Und so weiter: Im n-ten Jahr wird Ihr Kapital mit n multipliziert, und wir nehmen nur 1 Dollar Gebühren. Interessant, nicht wahr?
Wie hoch wäre Ihr Kapital nach 25 Jahren?

Versucht mal obiges Angebot mit Single-, Double-, Currency- und Extended-Genauigkeit zu testen. Und dann können wir uns gemeinsam wundern.
Gruß, Andreas

TurboMagic 5. Apr 2020 19:28

AW: Genauigkeit von String to Single Konvertierung
 
Zitat:

Zitat von himitsu (Beitrag 1461305)
Es gibt auch noch was von negaH, das sauschnell ist. (DECMath, Hagen Reddmann)
Ich weiß grade nicht wie es dort aussieht, aber da wollte sich auch jemand aus der DP darum kümmern den Code auch für neuere Delphis zur Verfügung zu stellen (da damals nur als DCU verfügbar war)

Naja, DEC als Krypto Bibliothek wird ja, wenngleich mit niedrigem Tempo, weiterentwickelt. Heute wurde beispielsweise ein Bug beseitigt.

Nur DECMath wurde schon länger entfernt, da nur als D7 oder so DCU verfügbar. Ich wüsste auch nicht wer das übernommen hätte. Da hätte Hagen ja den Quellcode rausrücken müssen. Da habe ich aber keine Kenntnis darüber. DEC ist noch Arbeit genug, auch wenn sich da das eine oder andere in den letzten Jahren getan hat.

freimatz 6. Apr 2020 12:25

AW: Genauigkeit von String to Single Konvertierung
 
Zitat:

Zitat von jfheins (Beitrag 1461302)
Und es liegt auch daran, dass für geschätzt 99,999% aller Anwendungsfälle die normalen Gleitkommazahlen ausreichen (ggf. mit Rundung).
...
Was mir so als use case in den Sinn kommt ist typischerweise Finanzen, Kryptographie und Tschenrechner.

Und geschätzt 99,8% aller Anwendungsfälle benötigen gar keine Gleitkommazahlen. (Wenn nicht TDateTime als double definiert wäre :wall:)

Und wer bei Finanzen Fließkomma nimmt gehört virtuell ...

Andreas13 6. Apr 2020 17:31

AW: Genauigkeit von String to Single Konvertierung
 
Zitat:

Zitat von freimatz (Beitrag 1461396)
Zitat:

Zitat von jfheins (Beitrag 1461302)
Und es liegt auch daran, dass für geschätzt 99,999% aller Anwendungsfälle die normalen Gleitkommazahlen ausreichen (ggf. mit Rundung).
...
Was mir so als use case in den Sinn kommt ist typischerweise Finanzen, Kryptographie und Tschenrechner.

Und geschätzt 99,8% aller Anwendungsfälle benötigen gar keine Gleitkommazahlen. (Wenn nicht TDateTime als double definiert wäre :wall:)

Und wer bei Finanzen Fließkomma nimmt gehört virtuell ...

Ja, aber es kommt wirklich darauf an, für welche Zielgruppe man programmiert. Aber in der Technik, der gesamten Industrie, Ingenieur- und Naturwissenschaften braucht man zuverlässige Fließkomma-Berechnungen.
Mir fällt dazu ein Zitat vom "The Father of Floating Point" Prof. Dr. William Kahan (University of California, Berkeley) ein, der bekanntlich der Hauptarchitekt der Standards IEEE 754, IEEE 854 und IEEE 754r für die binären Gleitkommazahlen ("floating-point") ist, nach welchen die meisten unserer heutigen Prozessoren arbeiten. Er schrieb bereits im Jahre 1998 in einem Workshop-Beitrag über Dr. James Gosling (= "Dr. Java"), den Entwickler der Programmiersprache Java:
We agree with James Gosling about some things like ...
...
"95% of the folks out there are completely clueless about floating-point."
(James Gosling, 28 Feb. 1998)
(Maybe more than 95% ?: 1 March 1998, W. Kahan)
...
Das ist schon 22 Jahre her. Vielleicht wären heutzutage 99 % treffender...
Andreas

Redeemer 6. Apr 2020 23:03

AW: Genauigkeit von String to Single Konvertierung
 
Zitat:

Zitat von Andreas13 (Beitrag 1461321)
Das Angebot der "Chaotic Bank Society":
Sie zahlen zunächst e - 1 $ auf Ihr Konto ein, wobei e = 2. 7182818… ist die Basis der natürlichen Logarithmen. Im ersten Jahr nehmen wir 1 $ von Ihrem Konto als Bearbeitungsgebühren. Das zweite Jahr ist besser für Sie: Wir multiplizieren Ihr Kapital mit 2, und wir nehmen 1 $ Bearbeitungsgebühren von Ihrem Konto. Das dritte Jahr ist sogar noch besser: Wir vervielfachen Ihr Kapital durch 3, und wir nehmen immer nur noch 1 $ an Bearbeitungsgebühren. Und so weiter: Im n-ten Jahr wird Ihr Kapital mit n multipliziert, und wir nehmen nur 1 Dollar Gebühren. Interessant, nicht wahr?
Wie hoch wäre Ihr Kapital nach 25 Jahren?

Exakte Lösung: 25!e-sum(i=1;25;25!/i!)=15511210043330985984000000 e - 26652630354867072870693626
Numerische Lösungen:
Currency läuft bei der Berechnung für das 18. Jahr über.
1,5511210043330986E25 Delphi Extended
1,55112100433309861E25 Delphi Double
1,55112100433655498E25 Delphi Real48
1,55112076204817268E25 Delphi Single
1.551121004333098598400000003993872967323020890367 14552103610609810902462093999452735830887464108224 05958563231326504588526568754471550871321071511028 65877113031301246014269485947628156339035631478711 56972992927463959295378944403635902120260128114229 22313584223061180730596742377705289915144746694475 71765160508839459336338872383753196167221729140084 08174885201783691426388619978768865531323118535402 96935132579638126446952478348226578947288519178106 17781233401594055691040321590882201736459569823189 83576440408501342622021037730943274224144511437305 07152135683657708095677651120107759880605933613348 87623261771817480734410462774503249855758903025858 69911940277896932577548947296379441152499806651387 03945047390025867346621461272142961349666226182108 72695781997452163483694977937913381018485218277696 61754835986000967476233623861761063114702374959896 83244412722845433289358770989410202014274865145376 89535607054925229658200499120673138102661633964476 23628162987616065094362331757119278048209290555851 58236935322280549346093132963461058740654005374192 47677708355911819747675693712901378560713651778669 97931702493494721257361195123847186012238814637677 12722473351719813105096004887329666997611226438824 31479723969411331531960466717554616891283716351868 13994710337926333417096117724340263241126891726855 88792815973341240411885154432701216689096314639830 09978990008722755195406595058471067994822268098769 63303747291358036140174827459667579289634528150803 68253091530679796464656985926303187771471523090861 36065061715164522738784611354074952513726360974946 56039646541458858796075909681192962495110133421155 44819985771722994490313918182408598176122453110625 74591169349402523418996815901688696723377571156091 70072292208685849130844754758257019940278213507914 98166946886825456038719192553043078845960587978370 03347244591119333590346079381954256694073107837219 33247781048120121896075526893236023455770809887225 34810420772451347935461156084362437017435480228239 22559760804442565816753931503823148559605618238340 34744874760918148873772361146935820729137193550727 78518215627135770680812276472172702654725610074861 66588214391218906867367130029323735726017595848330 52442292727671467414360149211485363973833778677970 28508409906494296792769856861898977448447438021512 40224683859908687373538562542464740954057544917750 30797039732844954737644542762735245237821769200312 23083815968813598249665040371444008754885242844956 10815714710103809452472855113169849371253705634007 77569455614975853827444786365708317189821517395860 89568336769347793424220928780305804313696004710640 60120578457459017962608987107680998265372166730171 71552663089995959634861333788237138558214346778984 51463891214543327001686282548111614109449236925218 48770289602488971694917432865092216438082263294017 94514026323322533973103973760576676535163204324726 58430380533664963359848416627509384813851591111228 40097985233174471899577097597994574401395209375595 20279627770633530918788298081281794400221601973756 92787364229556555705724015912072278296173349441915 11570874137950251130442286114860282770673985838722 45727245695100078688147484750204795338668818271535 24614441317803722355359830604654842877184349597238 60273376226934553216173687765193470643343951239086 27784196075087827104944773669868914461184642437721 09432767417654171846730641402959136954307980191949 80295033188124985726393161784018920609632198659814 06100968138174080569252616515193753342340853705790 16941950615567101585464690380642434483220667815415 67830211036156076664570959191257605113039930671400 38505463543226353476234794904639287798040991945474 50131428588001563989984646910763702908587333364442 95562891565772491614838243280456415431605340E25 Eine recht genaue Darstellung

Bin enttäuscht, hatte größere Unterschiede erwartet.

himitsu 6. Apr 2020 23:12

AW: Genauigkeit von String to Single Konvertierung
 
Die ersten 5 Dezimalstellen sind identisch, also ist es egal.

Was kommt denn raus, wenn du bei/nach jeder Transaktion alles auf 2 bzw. 4 Nachkommastellen rundest?
Beim Einzahlen/Auszahlen natürlich die jeweiligen Beträge immer auf 2 Nachkommastellen.

Andreas13 7. Apr 2020 12:45

AW: Genauigkeit von String to Single Konvertierung
 
Es tut mir leid, aber ich habe es halt mit Zitaten. Diesmal eines von Karl Nickel über den Umgang mit ausgedruckten Ergebnissen einer numerischen Rechnung:

Der (naive) Anfänger glaubt an jede einzelne Ziffer.
Der (erfahrene) Programmierer vertraut auf die Hälfte der Stellen.
Der (wissende) Pessimist mißtraut sogar dem Vorzeichen.

Sorry, aber ich bin ein unverbesserlicher Pessimist…
Bitte den Algorithmus noch einmal überprüfen: Leider ist keine einzige Stelle korrekt. Zwischen den Lösungen der von Delphi angebotenen Fließkomma-Typen (Single, Double, Extended und Currency) liegen astronomische Unterschiede, nicht nach, sondern vor dem Komma. Bitte daher selber nachrechnen.
Warum ich es so spannend mache: Um uns die Augen zu öffnen, denn – und dann muß ich wieder eine Berühmtheit bemühen – nach dem Mathematiker- & Informatiker-Pionier Richard Hamming gilt:

The purpose of computing is insight, not numbers.

Und vielleicht verhilft uns diese simple Berechnung zu einer numerischen Einsicht & Erkenntnis.
Andreas

Andreas13 16. Apr 2020 21:18

AW: Genauigkeit von String to Single Konvertierung
 
Ich habe absichtlich einige Zeit gewartet, um zu testen, ob die beide Jungs mit ihrer Behauptung recht hätten:
Zitat:

Zitat von Andreas13 (Beitrag 1461445)
We agree with James Gosling about some things like ...
...
"95% of the folks out there are completely clueless about floating-point."
(James Gosling, 28 Feb. 1998)
(Maybe more than 95% ?: 1 March 1998, W. Kahan)
...
Das ist schon 22 Jahre her. Vielleicht wären heutzutage 99 % treffender...
Andreas

Anscheinend haben sie doch recht gehabt! Offenbar interessiert sich hier so gut wie niemand für die Genauigkeit von numerischen Berechnungen. Schade. Anderseits kann ich gut verstehen, wenn sich Integer-Programmierer nicht für Real-Zahlen interessieren. Jeder spezialisiert sich halt auf ein anderes Gebiet.
Nur für den Fall, daß sich hier zufällig auch mal ein Floating-Point-Interessierter verirrt, hier folgt die Auflösung des „Rätsels“ von # 23:
Die Lösung vo Redeamer:
Zitat:

Zitat von Redeemer (Beitrag 1461471)
Zitat:

Zitat von Andreas13 (Beitrag 1461321)
Das Angebot der "Chaotic Bank Society":
Sie zahlen zunächst e - 1 $ auf Ihr Konto ein, wobei e = 2. 7182818… ist die Basis der natürlichen Logarithmen. Im ersten Jahr nehmen wir 1 $ von Ihrem Konto als Bearbeitungsgebühren. Das zweite Jahr ist besser für Sie: Wir multiplizieren Ihr Kapital mit 2, und wir nehmen 1 $ Bearbeitungsgebühren von Ihrem Konto. Das dritte Jahr ist sogar noch besser: Wir vervielfachen Ihr Kapital durch 3, und wir nehmen immer nur noch 1 $ an Bearbeitungsgebühren. Und so weiter: Im n-ten Jahr wird Ihr Kapital mit n multipliziert, und wir nehmen nur 1 Dollar Gebühren. Interessant, nicht wahr?
Wie hoch wäre Ihr Kapital nach 25 Jahren?

Exakte Lösung: 25!e-sum(i=1;25;25!/i!)=15511210043330985984000000 e - 26652630354867072870693626
Numerische Lösungen:
Currency läuft bei der Berechnung für das 18. Jahr über.
1,5511210043330986E25 Delphi Extended
1,55112100433309861E25 Delphi Double
1,55112100433655498E25 Delphi Real48
1,55112076204817268E25 Delphi Single
1.551121004333098598400000003993872967323020890367 14552103610609810902462093999452735830887464108224 0595856323132650458
… und weitere über 3500 Ziffern

ist leider keine „Erlösung“, denn Deine Formel ist falsch. Darüber hinaus hast Du gemogelt, weil Du nicht einmal Deine eigene Formel mit den verschiedenen Real-Typen berechnet hast, sondern nur Deine allerletzte Operation: 15511210043330985984000000 e - 26652630354867072870693626. Du hast dabei allerdings Deine „Zwischenergebnisse“ per Hand, mittels MatLab, Maple, Mathematica, MPA-Bibliotheken oder auf einem anderen Weg zuvor ausgerechnet und diese Zahlen als Input für die „Berechnung“ benutzt. Wenn man die Genauigkeit verschiedener Real-Typen vergleichen will, muß man schon die gesamte Berechnung damit durchführen, nicht nur einen willkürlichen Schritt. Hättest Du wenigstens Deine eigene (= falsche) Formel 25!e - sum(i=1;25;25!/i!) verwendet, dann wären folgende „Guthaben“ rausgekommen:
Guthaben Single : nach 25 Jahren = ---> Überlauf!
Guthaben Currency: nach 25 Jahren = ---> Überlauf!
Guthaben Real : nach 25 Jahren = ---> Überlauf!
Guthaben Double : nach 25 Jahren = -4.1341454764160250E+0050
Guthaben Extended: nach 25 Jahren = -4.1341454764160244E+0050
Ich denke, dieses Ergebnis brauchen wir nicht weiter zu kommentieren.
Apropos:
Die korrekte Formel für das Guthaben lautet: Guthaben nach n Jahren = n!*((e – 1) – (1/1! + 1/2! + 1/3! … + 1/n!)) .
Und das korrekte Guthaben nach 25 Jahren beträgt genau 0,03993873… $, also knapp 4 Cent.

Die Berechnung des Guthabens im vorliegenden Fall über die Formel mit den Fakultäten ist bereits ein grober Verstoß gegen das „kleine ABC“ der Gleitkomma–Arithmetik & jedweder numerischen Rechenregeln, weil es hier um die Differenzbildung zweier riesengroßer Zahlen handelt. Die Fakultät von 25, also 25! = 15511210043330985984000000 ist eine Zahl mit 26 Ziffern. Dabei verliert unser „Double“ durch arithmetische Rundung „hinten“ bereits 8 bis 9 Ziffern. Selbst bei Extended bußen wir immer noch 6 ..7 Ziffern ein. Wenn davon eine ähnlich große Zahl subtrahiert werden sollen, dann gehen uns genauso viele Nachkommastellen „hinten“ – also genau im Ergebnis – flöten. Kein Wunder, daß hierbei ein ziemlich „ungewöhnliches“ Resultat rauskommt, welches wir getrost in den Papierkorb werfen können. Daher ist dieser Weg über Fakultäten – selbst bei der Verwendung von Multipräzisionsarithmetik – nicht zu empfehlen.
Allerdings geht es bei der Beispiel-Aufgabe um die Demonstration des möglichen verheerenden Effektes winziger Rundungsfehler, die je nach verwendetem Floating-Point-Type Single, Double, Extended bei ca. 1E-8, 1E-15 und 1E-18 liegen, aber sich u. U. beachtlich aufschaukeln können.
Und vor allem, man sollte seine Ergebnisse und Formeln stets gewissenhaft überprüfen und ausgiebig testen, bevor man eine Vielzahl von falschen Ziffern raushaut… Numerische Mathematik bringt einen oft zur Verzweiflung, aber sie macht einen vor allem etwas bescheidener…
Viel einfacher und anschaulicher ist daher folgende For - Schleife:
Delphi-Quellcode:

VAR
  i : Integer;
  Guthaben_s: Single;
  Guthaben_c: Currency;
  Guthaben_r: Real48;
  Guthaben_d: Double;
  Guthaben_x: Extended;

CONST
  Br = 25;
  St = 20;

      Guthaben_s:= exp(1) - 1;
      Guthaben_c:= exp(1) - 1;
      Guthaben_r:= exp(1) - 1;
      Guthaben_d:= exp(1) - 1;
      Guthaben_x:= exp(1) - 1;

      WriteLn('StartGuthaben: e - 1 => Single : ', Guthaben_s:Br:St);
      WriteLn('StartGuthaben: e - 1 => Currency: ', Guthaben_c:Br:St);
      WriteLn('StartGuthaben: e - 1 => Real   : ', Guthaben_r:Br:St);
      WriteLn('StartGuthaben: e - 1 => Double : ', Guthaben_d:Br:St);
      WriteLn('StartGuthaben: e - 1 => Extended: ', Guthaben_x:Br:St);
      WriteLn;    
           
      For i := 1 To 25 Do
      Begin
        Guthaben_s := Guthaben_s*i - 1;
        // Guthaben_c := Guthaben_c*i - 1; // Überlauf nach 21 Jahren!
        Guthaben_r:= Guthaben_r*i - 1;
        Guthaben_d := Guthaben_d*i - 1;
        Guthaben_x := Guthaben_x*i - 1;
        // WriteLn('Guthaben Double : nach ' + (i).ToString + ' Jahren = ', Guthaben_d:Br:St);      
        // WriteLn('Guthaben Extended: nach ' + (i).ToString + ' Jahren = ', Guthaben_x:Br:St);      
      End;

      WriteLn;
      WriteLn('Guthaben Single : nach ' + (i-1).ToString + ' Jahren = ', Guthaben_s:Br:St);
      // WriteLn('Guthaben Currency: nach ' + (i-1).ToString + ' Jahren = ', Guthaben_c:Br:St);
      WriteLn('Guthaben Currency: nach ' + (i-1).ToString + ' Jahren = ','---> Überlauf nach 21 Jahren!');
      WriteLn('Guthaben Real   : nach ' + (i-1).ToString + ' Jahren = ', Guthaben_r:Br:St);
      WriteLn('Guthaben Double : nach ' + (i-1).ToString + ' Jahren = ', Guthaben_d:Br:St);
      WriteLn('Guthaben Extended: nach ' + (i-1).ToString + ' Jahren = ', Guthaben_x:Br:St);
      WriteLn;
      WriteLn('Guthaben KORREKT : nach 25 Jahren = 0.0399387...');
Obige Berechnung liefert folgende Ergebnisse:

Guthaben Single : nach 25 Jahren = 5.68654735142289E+0017 (= 569 tausend Billionen!)
Guthaben Currency: nach 25 Jahren = ---> Überlauf nach 21 Jahren!
Guthaben Real : nach 25 Jahren = -1.30694632129600E+0013 (= -13 Billionen SCHULDEN!)
Guthaben Double : nach 25 Jahren = 1.20180724741045E+0009 (= 1,20 Milliarden!)
Guthaben Extended: nach 25 Jahren = 1.05291085275662E+0006 (= 1,05 Millionen!)

Guthaben KORREKT : nach 25 Jahren = 0.0399387...

Auch Excel rechnet uns arm:
Guthaben Excel Professional (2016): nach 25 Jahren = -2242373258,57016 (= -2,24 Milliarden SCHULDEN!)
Und je nach verwendetem Taschenrechner bekommen wir weitere recht „interessante“ Resultate.

Für die halbwegs korrekte Berechnung des Guthabens im 25-ten Jahr brauchen wir mindestens 30 wertvolle Ziffern, die Delphi von Haus nicht bietet. Interessant ist dabei, daß alle (korrekten) Zwischenergebnisse im Bereich 1,72 … 0 liegen: Es geht also um ganz „normale“ Alltags-Zahlen. Leider versagen hier alle „eingebauten“ Typen von Delphi. Excel – ein tolles Programm! – rechnet hier u .a. wegen eines winzigen Rundungsfehlers in der 15-ten Stelle bei der Zahl e) etwas falscher als Delphi‘s Double und bekommt für den Kontoinhaber anstelle des „erwarteten“ Milliarden-Guthabens einen beinahe doppelt so hohen Schuldenberg raus...
Dieses einfache Beispiel sollte uns zeigen, daß bei Gleitkomma-Berechnungen stets Vorsicht geboten ist. Selbst zuverlässige, fehlertolerante Algorithmen, Multipräzisions-Arithmetik und ausgiebige Tests sind keine Garantie vor gelegentlichen bösen Überraschungen.

Aber ich denke, es genügt: Schließlich interessiert es hier eh niemanden.
Gruß, Andreas


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:14 Uhr.
Seite 3 von 4     123 4      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz