[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] Calculate mantissa and exponent?


Subject: Re: [xsl] Calculate mantissa and exponent?
From: Michael Case <mecase@xxxxxxxxxxx>
Date: Fri, 10 Aug 2001 10:46:58 -0700

Hi,

Here goes.  I hope this is message is not too long.  

Any help/advice to shorten the ConvertSciToNumString.xsl, or make it in
anyway "better" would be appreciated.  I am not yet very good at xsl.

Mike Case

xml test suite:

<main>
  <mynum num="1"/>
  <mynum num="-2"/>
  <mynum num="3E-3"/>
  <mynum num="-2E-4"/>
  <mynum num=".5E-3"/>
  <mynum num=".3E4"/>
  <mynum num=".2E-4"/>
  <mynum num="-.6E3"/>
  <mynum num="-.6E-4"/>
  <mynum num="6.022E23"/>
  <mynum num=".312E1"/>
  <mynum num="312E-2"/>
  <mynum num="-0.312E1"/>
  <mynum num="-312E-2"/>
  <mynum num="923.9E-1"/>
  <mynum num="1.625E-12"/>
  <mynum num="1.E-5"/>
  <mynum num="2.14160E-3"/>
  <mynum num="2.14160e-3"/>
</main>

---------------------------------
use of template:

<xsl:stylesheet
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   version="1.0"
>
<!--
	Example usage of ConvertSciToNumString.xsl
-->

<xsl:template match="/">
  <html>
    <head>
      <title>Output for web page</title>
    </head>
    <body>
      <xsl:apply-templates/>
    </body>
  </html>
</xsl:template>

<xsl:template match="main">
  <table border="1" align="center">
    <th>num</th>
    <th>converted</th>    
    <th>number()</th>
    <xsl:apply-templates/>
  </table>
</xsl:template>

<xsl:template match="mynum">
  <tr>
    <td><xsl:value-of select="@num"/></td>
    <td>
      <xsl:call-template name="convertSciToNumString">
        <xsl:with-param name="myval" select="@num"/>
      </xsl:call-template>
    </td>
    <td><xsl:value-of select="number(@num)"/></td>
  </tr>
</xsl:template>

<xsl:include href="ConvertSciToNumString.xsl"/>

</xsl:stylesheet>

---------------------------------
ConvertSciToNumString.xsl

<xsl:stylesheet
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   version="1.0"
>

<xsl:output method="xml"/>
<!--
	ConvertSciToNumString 
	By: 	Michael Case
		University of California, Davis
		case@xxxxxxxxxxxxxxxxxx


	Converts a string from Scientific notation to an XML acceptable number
(as a string).
	e.g. convert from 1E-10 to 0.0000000001

	Include this template in your XSL file using: <xsl:include
href="ConvertSciToNumString.xsl">

	Input parameters to ConvertSciToNumString
		myval		the number to be checked.

	Input parameters to realConvertSciToNumString (base 10 assumed):
		vnum		the un-signed mantissa
		sgn		the sign, an empty string or '-'

	This puts out a text result which can be enclosed in the calling XSL
with <xsl:element>,
	<xsl:attribute> or nothing (leave as text). 

-->

<!-- necessary global maximum/minimum of exponent 'stuffer', set to 100
-->
<xsl:variable name="max-exp">
  <xsl:value-of
select="'0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'"/>
</xsl:variable>

<xsl:template name="convertSciToNumString">
  <xsl:param name="myval" select="''"/>
  <xsl:variable name="useval">
    <xsl:value-of select="translate(string($myval),'e','E')"/>
  </xsl:variable>

  <xsl:choose>
    <xsl:when test="not(number($useval))">
      <xsl:choose>
        <xsl:when test="number(substring-before($useval, 'E'))">

          <xsl:choose>
            <xsl:when test="number(substring-after($useval, 'E'))">
              <xsl:if test="number(substring-before($useval, 'E')) &lt;
0">
                <xsl:call-template name="realConvertSciToNumString">
                  <xsl:with-param name="vnum"
select="substring-after($useval, '-')"/>
                  <xsl:with-param name="vsgn" select="'-'"/>
                </xsl:call-template>
              </xsl:if>
              <xsl:if test="number(substring-before($useval, 'E')) &gt;
0">
                <xsl:call-template name="realConvertSciToNumString">
                  <xsl:with-param name="vnum" select="$useval"/>
                </xsl:call-template>
              </xsl:if>
            </xsl:when>

            <xsl:otherwise>
              <xsl:value-of select="$useval"/>
            </xsl:otherwise>

          </xsl:choose>
        </xsl:when>

        <xsl:otherwise>
          <xsl:value-of select="$useval"/>
        </xsl:otherwise>

      </xsl:choose>
    </xsl:when>

    <xsl:otherwise>
      <xsl:value-of select="number($useval)"/>
    </xsl:otherwise>

  </xsl:choose>
</xsl:template>

<xsl:template name="realConvertSciToNumString" >
  <xsl:param name="vnum" select="0"/>
  <xsl:param name="vsgn" select="''"/>
  <xsl:choose>
    <xsl:when test="number(vnum)">
      <xsl:value-of select="$vnum"/>
    </xsl:when> 
    <xsl:otherwise>
            <xsl:variable name="vmantisa">
              <xsl:value-of select="number(substring-before($vnum,
'E'))"/>
            </xsl:variable>
            <xsl:variable name="vexponent">
              <xsl:value-of select="number(substring-after($vnum,
'E'))"/>
            </xsl:variable>

            <!--  handle 0.9.... -->
            <xsl:if test="$vmantisa &lt; 1">

              <!-- handle 0.9E-9 -->
              <xsl:if test="$vexponent &lt; 0">
                <xsl:variable name="voffset">
                  <xsl:value-of
select="string-length(substring-before($vmantisa, '.'))"/>
                </xsl:variable>
                    <xsl:value-of select="concat($vsgn, '0', '.',
substring($max-exp, 1, ($vexponent * -1) -
$voffset),substring-before($vmantisa,'.'), substring-after($vmantisa,
'.'))"/>
              </xsl:if>

              <!-- handle 0.9E9 -->
              <xsl:if test="$vexponent &gt; 0">
                <xsl:variable name="voffset">
                  <xsl:value-of
select="string-length(substring-after($vmantisa, '.'))"/>
                </xsl:variable>

                <xsl:choose>
                  <!-- handle .932E1 -->
                  <xsl:when test="$voffset &gt; $vexponent">
                      <xsl:value-of select="concat($vsgn,
substring(substring-after($vmantisa, '.'), 1, $vexponent), '.',
substring(substring-after($vmantisa, '.'), $vexponent + 1,
string-length($vmantisa) - $vexponent))"/>
                  </xsl:when>

                  <!-- handle .9E3 -->
                  <xsl:when test="$voffset &lt; $vexponent">
                      <xsl:value-of select="concat($vsgn,
substring-after($vmantisa, '.'), substring($max-exp, 1, ($vexponent -
$voffset)))"/>
                  </xsl:when>

                  <!-- handle .9E1 -->
                  <xsl:when test="$voffset = $vexponent">
                      <xsl:value-of select="concat($vsgn,
substring-before($vmantisa, '.'), substring-after($vmantisa, '.'))"/>
                  </xsl:when>

                  <xsl:otherwise>
                      <xsl:value-of select="NaN"/>
                  </xsl:otherwise>

                </xsl:choose>

              </xsl:if>
            </xsl:if>

            <!-- handle 9.9.... -->
            <xsl:if test="$vmantisa &gt;= 1">

              <!-- handle 9.9E-9 -->
              <xsl:if test="$vexponent &lt; 0">
                <xsl:variable name="voffset">
                  <xsl:value-of
select="string-length(substring-before($vmantisa, '.'))"/>
                </xsl:variable>

                <xsl:choose>

                  <!-- really handle 923.9E-1 -->
                  <xsl:when test="$voffset &gt; $vexponent * -1">
                      <xsl:value-of select="concat($vsgn,
substring(substring-before($vmantisa, '.'), 1,
string-length(substring-before($vmantisa, '.')) + $vexponent), '.',
substring(substring-before($vmantisa, '.'),
string-length(substring-before($vmantisa, '.')) + $vexponent + 1,
$vexponent * -1), substring-after($vmantisa, '.'))"/>
                  </xsl:when>

                  <!-- really handle 9.9E-9 -->
                  <xsl:when test="$voffset &lt; $vexponent * -1 and
$voffset &gt; 0">
                      <xsl:value-of select="concat($vsgn, '0', '.',
substring($max-exp, 1, ($vexponent * -1) - $voffset),
substring-before($vmantisa, '.'), substring-after($vmantisa, '.'))"/>
                  </xsl:when>

                  <!-- handle 9.9E-1 -->
                  <xsl:when test="$voffset = $vexponent * -1 and
$voffset &gt; 0">
                      <xsl:value-of select="concat($vsgn, '0', '.',
substring-before($vmantisa, '.'), substring-after($vmantisa, '.'))"/>
                  </xsl:when>

                  <!-- handle 9E-9 -->
                  <xsl:when test="$voffset = 0 and
string-length($vmantisa) &lt; $vexponent * -1">
                      <xsl:value-of select="concat($vsgn, '0', '.',
substring($max-exp, 1, ($vexponent * -1) - string-length($vmantisa)),
$vmantisa)"/>
                  </xsl:when>

                  <!-- handle 999E-1-->
                  <xsl:when test="$voffset = 0 and
string-length($vmantisa) &gt; $vexponent * -1">
                      <xsl:value-of select="concat($vsgn,
substring($vmantisa, 1, string-length($vmantisa) + $vexponent), '.',
substring($vmantisa, string-length($vmantisa) + $vexponent + 1,
$vexponent * -1))"/>
                  </xsl:when>

                  <xsl:otherwise>
                      <xsl:value-of select="'NaN'"/>
                  </xsl:otherwise>

                </xsl:choose>

              </xsl:if>

              <!-- handle 9.9E9 -->
              <xsl:if test="$vexponent &gt; 0">
                <xsl:variable name="voffset">
                  <xsl:value-of
select="string-length(substring-after($vmantisa, '.'))"/>
                </xsl:variable>
                <xsl:value-of select="concat($vsgn,
substring-before($vmantisa, '.'), substring-after($vmantisa, '.'),
substring($max-exp, 1, ($vexponent - 1 - $voffset)))"/>
              </xsl:if>
            </xsl:if>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

</xsl:stylesheet


Bruce Kyle wrote:
> 
> Absolutely interested.  Would you mind posting it?
> 
> bruce
> 
> -----Original Message-----
> From:   Michael Case [SMTP:mecase@xxxxxxxxxxx]
> Sent:   Friday, August 10, 2001 9:36 AM
> To:     xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject:        Re: [xsl] Calculate mantissa and exponent?
> 
> Hi,
> 
> Thanks for this.  I wrote something going the opposite way and wonder if
> there is any interest for that?  I can send it to the list or to an
> someone else if they are interested.
> 
> Sincerely,
> 
> Michael Case
> 
> "Mitchell, Edmund" wrote:
> >
> > Thanks, Tim.  I did, and it was a small part of what I needed.  If anyone
> > else needs it, here it is, courtesy of sdussinger:
> >
> > sample.xml:
> >
> > <a>
> >   <num>0.00000004</num>
> >   <num>123456</num>
> >   <num>-756444</num>
> > </a>
> >
> ... stuff deleted
> --
> Michael E. Case
> UC Davis
> case@xxxxxxxxxxxxxxxxxx
> (530) 754-7226
> 
>  XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list

-- 
Michael E. Case
UC Davis
case@xxxxxxxxxxxxxxxxxx
(530) 754-7226

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list



Current Thread
Keywords