challenge 16進数から10進数の変換

16進数を10進数に変換してください。

ただし、入出力は文字列とし、次の変換は最低必ずできなければいけないこととします。

  1. 0x12437308CCB6 →20080902065334

2.0x2C9C1227FC6520B →200904012311450123

あわせて、扱える最大の整数も明らかにしてください。

Posted feedbacks - XSLT

XSLT1.0で実装。
XPath1.0の数値型は浮動小数点数しか存在せず、その精度は処理系によって異なるようです。倍精度くらいで実装されているようで、この数値型をそのまま利用すると(29-51行)、条件2の変換が正確に行えませんでした。
そこで、入力された16進数を上位ビットと下位ビットに分けて数値化し、10進数として表示する時に2つの数を合成する手法を用いました(52-95行)。それでもFirefoxだと16桁でヘタってしまいましたが、Xalanは26桁まで頑張ってくれました。

実行結果(実行方法:適当なXMLにこのXSLTを適用)
 - Firefox 3.5.1:
0x12437308CCB6 = 20080902065334.
0x2C9C1227FC6520B = 200904012311450100.
0x12437308CCB6 = (bignum) 20080902065334.
0x2C9C1227FC6520B = (bignum) 200904012311450123.
0xCDEF89AB45670123 = (bignum) 14839230665905865403.
0x112233445566778899AABBCCDD = (bignum) 1357463230989497420518412782813.

 - Xalan 1.10.0:
0x12437308CCB6 = 20080902065334.
0x2C9C1227FC6520B = 200904012311450112.
0x12437308CCB6 = (bignum) 20080902065334.
0x2C9C1227FC6520B = (bignum) 200904012311450123.
0xCDEF89AB45670123 = (bignum) 14839230665905864995.
0x112233445566778899AABBCCDD = (bignum) 1357463230989497419223659171037.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="text" />
  <xsl:variable name="var" select="document('')/xsl:stylesheet/xsl:template[@name='var']" />
  <xsl:template match="/">
    <xsl:variable name="test1" select="'0x12437308CCB6'" />
    <xsl:variable name="test2" select="'0x2C9C1227FC6520B'" />
    <xsl:variable name="test3" select="'0xCDEF89AB45670123'" />
    <xsl:variable name="test4" select="'0x112233445566778899AABBCCDD'" />
    <xsl:call-template name="hex2dec">
      <xsl:with-param name="input" select="$test1" />
    </xsl:call-template>
    <xsl:call-template name="hex2dec">
      <xsl:with-param name="input" select="$test2" />
    </xsl:call-template>
    <xsl:call-template name="bighex2dec">
      <xsl:with-param name="input" select="$test1" />
    </xsl:call-template>
    <xsl:call-template name="bighex2dec">
      <xsl:with-param name="input" select="$test2" />
    </xsl:call-template>
    <xsl:call-template name="bighex2dec">
      <xsl:with-param name="input" select="$test3" />
    </xsl:call-template>
    <xsl:call-template name="bighex2dec">
      <xsl:with-param name="input" select="$test4" />
    </xsl:call-template>
  </xsl:template>
  <xsl:template name="hex2dec">
    <xsl:param name="input" />
    <xsl:value-of select="$input" /> = <!--
    --><xsl:apply-templates select="$var" mode="translate">
      <xsl:with-param name="input" select="substring($input,3)" />
    </xsl:apply-templates>.
<!--
  --></xsl:template>
  <xsl:template match="xsl:template" mode="translate">
    <xsl:param name="input"  />
    <xsl:param name="output" select="0" />
    <xsl:choose>
      <xsl:when test="$input=''">
        <xsl:value-of select="$output" />
      </xsl:when>
      <xsl:otherwise>
        <xsl:apply-templates select="." mode="translate">
          <xsl:with-param name="input" select="substring($input,2)" />
          <xsl:with-param name="output" select="$output * 16 + hex[@name=substring($input,1,1)]" />
        </xsl:apply-templates>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  <xsl:template name="bighex2dec">
    <xsl:param name="input" />
    <xsl:variable name="partition" select="floor((string-length($input)-2) div 2)" />
    <xsl:value-of select="$input" /> = (bignum) <!--
    --><xsl:apply-templates select="$var" mode="btranslate">
      <xsl:with-param name="input" select="substring($input,3,$partition)" />
      <xsl:with-param name="input2" select="substring($input,3+$partition)" />
    </xsl:apply-templates>.
<!--
  --></xsl:template>
  <xsl:template match="xsl:template" mode="btranslate">
    <xsl:param name="input" select="''" />
    <xsl:param name="input2" select="''" />
    <xsl:param name="output" select="0" />
    <xsl:param name="output2" select="0" />
    <xsl:variable name="in1" select="substring($input,1,1)" />
    <xsl:choose>
      <xsl:when test="$input=''">
        <xsl:choose>
          <xsl:when test="$input2=''">
            <xsl:variable name="outA" select="substring($output,1,string-length($output)-string-length($output2))" />
            <xsl:variable name="outB" select="substring($output,string-length($output)-string-length($output2)+1) + $output2" />
            <xsl:variable name="overflow" select="number(string-length($outB)>string-length($output2))" />
            <xsl:value-of select="$outA + $overflow" />
            <xsl:value-of select="substring($outB,1+$overflow)" />
          </xsl:when>
          <xsl:otherwise>
            <xsl:apply-templates select="." mode="btranslate">
              <xsl:with-param name="input2" select="substring($input2,2)" />
              <xsl:with-param name="output" select="$output*16" />
              <xsl:with-param name="output2" select="$output2 * 16 + hex[@name=substring($input2,1,1)]" />
            </xsl:apply-templates>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:when>
      <xsl:otherwise>
        <xsl:apply-templates select="." mode="btranslate">
          <xsl:with-param name="input" select="substring($input,2)" />
          <xsl:with-param name="input2" select="$input2" />
          <xsl:with-param name="output" select="$output * 16 + hex[@name=substring($input,1,1)]" />
        </xsl:apply-templates>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  <xsl:template match="text()" mode="translate" />
  <xsl:template match="text()" mode="btranslate" />
  <xsl:template match="text()" />
  <xsl:template name="var">
    <hex name="0">0</hex>
    <hex name="1">1</hex>
    <hex name="2">2</hex>
    <hex name="3">3</hex>
    <hex name="4">4</hex>
    <hex name="5">5</hex>
    <hex name="6">6</hex>
    <hex name="7">7</hex>
    <hex name="8">8</hex>
    <hex name="9">9</hex>
    <hex name="A">10</hex>
    <hex name="B">11</hex>
    <hex name="C">12</hex>
    <hex name="D">13</hex>
    <hex name="E">14</hex>
    <hex name="F">15</hex>
  </xsl:template>
</xsl:stylesheet>

Index

Feed

Other

Link

Pathtraq

loading...