Zahlen auf eine angegebene Genauigkeit runden

(Auszug aus "XSLT Kochbuch" von Sal Mangano)

Problem

Sie wollen auf eine bestimmte Anzahl von Kommastellen runden, allerdings bilden die XSLT-Funktionen round, ceiling und floor Zahlen immer auf Integer-Werte ab.

Lösung

XSLT 1.0

Multiplizieren, runden und dividieren Sie um eine Zehnerpotenz, wodurch festgelegt wird, wie viele Kommastellen erforderlich sind. Nehmen Sie an, $pi = 3,1415926535897932

<xsl:value-of select="round($pi * 10000) div 10000"/>

ergibt 3,1416. Gleichermaßen ergibt

<xsl:value-of select="ceiling($pi * 10000) div 10000"/>

3,1416 und

<xsl:value-of select="floor($pi * 10000) div 10000"/>

3,1415.

Das Runden auf eine bestimmte Anzahl von Dezimalstellen wird auch mittels format-number( ) erreicht:

<xsl:value-of select="format-number($pi,'#.####')"/>

Das Ergebnis lautet hier 3,1416. Dies funktioniert sogar dann, wenn mehr als eine signifikante Ziffer im ganzen Teil ist, da format-number eine Formatspezifikation niemals dazu verwendet, um signifikante Ziffern aus dem ganzen Teil zu entfernen:

<xsl:value-of select="format-number($pi * 100,'#.####')"/>

Das Ergebnis lautet 314,1593.

Sie können format-number einsetzen, um etwas abzuschneiden, anstatt es zu runden, indem Sie eine Formatierungsstelle mehr benutzen, als erforderlich ist, und dann das letzte Zeichen abschneiden:

<xsl:variable name="pi-to-5-sig" select="format-number($pi,'#.#####')"/> 
<xsl:value-of select="substring($pi-to-5-sig,1,string-length($pi-to-5-sig) −1)"/>

Das Ergebnis lautet 3,1415.

XSLT 2.0

Die neue XPath 2.0-Funktion round-half-to-even( ) erledigt die Aufgabe für die meisten Anwendungen. Die half-to-even-Regel bedeutet Folgendes: Liegt der zu rundende Wert genau zwischen dem niedrigeren und dem höheren Wert, erfolgt die Rundung auf den Wert, der ein gerades Ergebnis erzeugt. Das bedeutet, round-half-to-even(1.115,2) ergibt 1.12, und round-half-to-even(1.125,2) ergibt ebenfalls 1.12! Im ersten Fall runden wir auf, weil 2 gerade ist, und im zweiten Fall runden wir ab, weil drei nicht gerade ist. Die Theorie dahinter lautet, dass Sie bei einer Menge von Zahlen etwa genauso oft auf- wie abrunden sollten, um Rundungsfehler auszugleichen. Wie Sie vermutlich bereits erraten haben, gibt das zweite Argument die Anzahl der Kommastellen an, auf die gerundet werden soll.

Falls Ihre Anwendung fordert, dass bei einer 5 an der letzten Kommastelle immer aufgerundet werden soll, können Sie die Techniken einsetzen, die im XSLT 1.0-Rezept vorgestellt werden.

Diskussion

Die Technik zum Multiplizieren, Runden und Dividieren funktioniert ganz gut, solange sich die beteiligten Zahlen innerhalb der Darstellungsgrenzen für IEEE-Gleitkommawerte bewegen. Falls Sie versuchen, zu viele Stellen nach dem Komma zu erfassen, kollidieren die Regeln für IEEE-Gleitkommawerte mit dem erwarteten Ergebnis. Falls Sie beispielsweise versuchen, 16 Dezimalstellen von pi zu bekommen, erhalten Sie nur 15:

<xsl:value-of select="round($pi * 10000000000000000) div 10000000000000000"/>

Das Ergebnis lautet dann 3,141592653589793, nicht 3,1415926535897932.

Eine alternative Technik manipuliert die Zahl als String und schneidet ab:

<xsl:value-of select="concat(substring-before($pi,'.'), '.', substring(substring-after($pi,'.'),1,4))"/>

Das Ergebnis lautet 3,1415.

Die Wirkung von ceiling oder round kann um den Preis zusätzlicher Komplexität mittels dieser Technik erzielt werden:

<xsl:variable name="whole" select="substring-before($pi,'.')"/>
<xsl:variable name="frac" select="substring-after($pi,'.')"/>
<xsl:value-of select="concat($whole, '.', substring($frac,1,3), round(substring($frac,4,2) div 10))"/>

Das Ergebnis lautet 3,1416.

  

<< zurück vor >>

 

 

 

Tipp der data2type-Redaktion:
Zum Thema XSLT bieten wir auch folgende Schulungen zur Vertiefung und professionellen Fortbildung an:

Copyright © 2006 O'Reilly Verlag GmbH & Co. KG
Für Ihren privaten Gebrauch dürfen Sie die Online-Version ausdrucken.
Ansonsten unterliegt dieses Kapitel aus dem Buch "XSLT Kochbuch" denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

O'Reilly Verlag GmbH & Co. KG, Balthasarstraße 81, 50670 Köln, kommentar(at)oreilly.de