title: XSLT 2.0: Rounding result of calculation to two decimals
body: <p>I am using xslt 2.0 and Saxon 9.6, and need to multiply a price amount and quantity, and then round the result to two decimals.I do not want banker's rounding, I want to round so .495 = 0.50 and .494 = .49.  I have tried read several articles and posts regarding this issue, but I cannot find the solution. I see several places that rounding with xslt 1.0 is problematic because of the floating point issue, and a lot of mentions that the xslt 2.0 and the xs:decimal should do the trick, but I cannot seem to find a "waterproof" solution.</p>
  
  <p>I have an xml file (Invoice) with 4 different InvoiceLines containing a price and a quantity element:</p>
  
  
  
  <pre><code>&lt;Invoice&gt;
  &lt;ID&gt;12345&lt;/ID&gt;
  &lt;IssueDate&gt;2012-11-21&lt;/IssueDate&gt;
  
  &lt;Supplier&gt;
      &lt;Party&gt;
          &lt;ID&gt;977187761&lt;/ID&gt;
      &lt;/Party&gt;
  &lt;/Supplier&gt;
  &lt;Customer&gt;
      &lt;Party&gt;
          &lt;ID schemeID="NO:ORGNR"&gt;810305282&lt;/ID&gt;
      &lt;/Party&gt;
  &lt;/Customer&gt;
  &lt;Delivery&gt;
      &lt;DeliveryDate&gt;2012-11-21&lt;/DeliveryDate&gt;
  &lt;/Delivery&gt;
  &lt;TaxTotal&gt;
      &lt;TaxAmount currencyID="NOK"&gt;128.89&lt;/TaxAmount&gt;
  &lt;/TaxTotal&gt;
  &lt;InvoiceLine&gt;
      &lt;ID&gt;1&lt;/ID&gt;
      &lt;Quantity unitCode="EA"&gt;19&lt;/Quantity&gt;
      &lt;LineAmount currencyID="NOK"&gt;130.26&lt;/LineAmount&gt;
      &lt;Item&gt;
          &lt;Name&gt;TestItem&lt;/Name&gt;
      &lt;/Item&gt;
      &lt;Price currencyID="NOK"&gt;8.569736842105263&lt;/Price&gt;
  &lt;/InvoiceLine&gt;
  &lt;InvoiceLine&gt;
      &lt;ID&gt;2&lt;/ID&gt;
      &lt;Quantity unitCode="NAR"&gt;1.00&lt;/Quantity&gt;
      &lt;LineAmount currencyID="NOK"&gt;128.2&lt;/LineAmount&gt;
      &lt;Item&gt;
          &lt;Name&gt;Vare A&lt;/Name&gt;
      &lt;/Item&gt;
      &lt;Price currencyID="NOK"&gt;128.195&lt;/Price&gt;
  &lt;/InvoiceLine&gt;
  &lt;InvoiceLine&gt;
      &lt;ID&gt;3&lt;/ID&gt;
      &lt;Quantity unitCode="NAR"&gt;1.00&lt;/Quantity&gt;
      &lt;LineAmount currencyID="NOK"&gt;128.7&lt;/LineAmount&gt;
      &lt;Item&gt;
          &lt;Name&gt;Vare B&lt;/Name&gt;
      &lt;/Item&gt;
      &lt;Price currencyID="NOK"&gt;128.695&lt;/Price&gt;
  &lt;/InvoiceLine&gt;
  &lt;InvoiceLine&gt;
      &lt;ID&gt;4&lt;/ID&gt;
      &lt;Quantity unitCode="NAR"&gt;1.00&lt;/Quantity&gt;
      &lt;LineAmount currencyID="NOK"&gt;128.4&lt;/LineAmount&gt;
      &lt;Item&gt;
          &lt;Name&gt;Vare C&lt;/Name&gt;
      &lt;/Item&gt;
      &lt;Price currencyID="NOK"&gt;128.395&lt;/Price&gt;
  &lt;/InvoiceLine&gt;
  </code></pre>
  
  <p></p>
  
  <p>I have run the following xslt on the xml:</p>
  
  <p></p>
  
  <pre><code>&lt;xsl:template match="/"&gt;
      &lt;html&gt;
          &lt;body&gt;
              &lt;xsl:for-each select="//InvoiceLine"&gt;
                  &lt;tr&gt;
  
                      &lt;td&gt;Line: &lt;xsl:value-of select="ID"/&gt;  &lt;/td&gt;
  
                      &lt;td&gt;Price: &lt;xsl:value-of select="Price"/&gt;&lt;/td&gt;
  
                      &lt;td&gt;Quantity: &lt;xsl:value-of select="Quantity"/&gt;&lt;/td&gt;
  
                      &lt;td&gt;LineAmount: &lt;xsl:value-of select="LineAmount"/&gt;&lt;/td&gt;
  
                      &lt;td&gt;P*Q: &lt;xsl:value-of select="Price * Quantity"/&gt;&lt;/td&gt;
  
                      &lt;td&gt;Round(p*q*100)div 100: &lt;xsl:value-of select="round((Price * Quantity * 100)) div 100" /&gt;&lt;/td&gt;
  
                      &lt;td&gt;xs:decimal(p*q): &lt;xsl:value-of select="xs:decimal(Price * Quantity)" /&gt;&lt;/td&gt;
  
                      &lt;td&gt;round((p*q)*10*10) div 100: &lt;xsl:value-of select="round((Price * Quantity) * 10 * 10) div 100"/&gt;&lt;/td&gt;
  
  
                  &lt;/tr&gt;
              &lt;/xsl:for-each&gt;
          &lt;/body&gt;
      &lt;/html&gt;
  &lt;/xsl:template&gt;
  </code></pre>
  
  <p></p>
  
  <p>And this is the result:</p>
  
  <pre><code>&lt;html xmlns:saxon="http://saxon.sf.net/" xmlns:op="http://www.w3.org/2002/08/xquery-operators" xmlns:schold="http://www.ascc.net/xml/schematron" xmlns:iso="http://purl.oclc.org/dsdl/schematron" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:ubl="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"&gt;
     &lt;body&gt;
    &lt;tr&gt;
       &lt;td&gt;Line: 1&lt;/td&gt;
       &lt;td&gt;Price: 8.569736842105263&lt;/td&gt;
       &lt;td&gt;Quantity: 19&lt;/td&gt;
       &lt;td&gt;LineAmount: 130.26&lt;/td&gt;
       &lt;td&gt;P*Q: 162.825&lt;/td&gt;
       &lt;td&gt;Round(p*q*100)div 100: 162.82&lt;/td&gt;
       &lt;td&gt;xs:decimal(p*q): 162.82499999999998863131622783839702606201171875&lt;/td&gt;
       &lt;td&gt;round((p*q)*10*10) div 100: 162.83&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
       &lt;td&gt;Line: 2&lt;/td&gt;
       &lt;td&gt;Price: 128.195&lt;/td&gt;
       &lt;td&gt;Quantity: 1.00&lt;/td&gt;
       &lt;td&gt;LineAmount: 128.2&lt;/td&gt;
       &lt;td&gt;P*Q: 128.195&lt;/td&gt;
       &lt;td&gt;Round(p*q*100)div 100: 128.2&lt;/td&gt;
       &lt;td&gt;xs:decimal(p*q): 128.19499999999999317878973670303821563720703125&lt;/td&gt;
       &lt;td&gt;round((p*q)*10*10) div 100: 128.19&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
       &lt;td&gt;Line: 3&lt;/td&gt;
       &lt;td&gt;Price: 128.695&lt;/td&gt;
       &lt;td&gt;Quantity: 1.00&lt;/td&gt;
       &lt;td&gt;LineAmount: 128.7&lt;/td&gt;
       &lt;td&gt;P*Q: 128.695&lt;/td&gt;
       &lt;td&gt;Round(p*q*100)div 100: 128.7&lt;/td&gt;
       &lt;td&gt;xs:decimal(p*q): 128.69499999999999317878973670303821563720703125&lt;/td&gt;
       &lt;td&gt;round((p*q)*10*10) div 100: 128.69&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
       &lt;td&gt;Line: 4&lt;/td&gt;
       &lt;td&gt;Price: 128.395&lt;/td&gt;
       &lt;td&gt;Quantity: 1.00&lt;/td&gt;
       &lt;td&gt;LineAmount: 128.4&lt;/td&gt;
       &lt;td&gt;P*Q: 128.395&lt;/td&gt;
       &lt;td&gt;Round(p*q*100)div 100: 128.4&lt;/td&gt;
       &lt;td&gt;xs:decimal(p*q): 128.395000000000010231815394945442676544189453125&lt;/td&gt;
       &lt;td&gt;round((p*q)*10*10) div 100: 128.4&lt;/td&gt;
    &lt;/tr&gt;
  </code></pre>
  
  <p>
  </p>
  
  <p>As you can see, I get different results of the different types of calculations/rounding. For line 1 I get the exptected result in the last calculation, but for line 2 and 3, this calculation does not give me the exptected result. </p>
  
  <p>I would be very greatful for any tips on how to solve this.</p>