.net XSLT mod检查是否存在大数

.net XSLT mod检查是否存在大数,.net,xml,xslt,xpath,modulus,.net,Xml,Xslt,Xpath,Modulus,我试图在XSLT1.0中对17位数字执行模数11检查。然而,它似乎总是给出错误的输出 我能找到的关于这一点的唯一信息是在,但是,没有找到解决方案 我过去曾将XSLT模板用于Luhn检查器,我意识到这与模数检查的工作方式不同,但我想知道是否有人知道XSLT模板可以计算大数的模数?这是因为在MSXML中,数字类型相当于.NETDouble数据类型,其精度为15-16位。 请尝试以下示例: double d = 123456789012345678; Console.WriteLine("{0:f}"

我试图在XSLT1.0中对17位数字执行模数11检查。然而,它似乎总是给出错误的输出

我能找到的关于这一点的唯一信息是在,但是,没有找到解决方案


我过去曾将XSLT模板用于Luhn检查器,我意识到这与模数检查的工作方式不同,但我想知道是否有人知道XSLT模板可以计算大数的模数?

这是因为在MSXML中,数字类型相当于.NET
Double
数据类型,其精度为15-16位。 请尝试以下示例:

double d = 123456789012345678;
Console.WriteLine("{0:f}", d);
Console.WriteLine("{0:f}", d + 1);
Console.WriteLine("{0:f}", d % 3);

long l = 123456789012345678;
Console.WriteLine(l);
Console.WriteLine(l + 1);
Console.WriteLine(l % 3);
输出:

123456789012346000,00
123456789012346000,00
2,00
123456789012345678
123456789012345679
0
我认为可以使用C#或JScript扩展XSLT,因为MSXML支持这一点


参考:,

有一个纯XSLT 1.0解决方案,它为任何大小的整数
$n
计算
$n mod 11

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/*">
     <xsl:call-template name="mod11"/>
 </xsl:template>

 <xsl:template name="mod11">
  <xsl:param name="pN" select="."/>

  <xsl:choose>
   <xsl:when test="not($pN > 9999999999999999)">
     <xsl:value-of select="$pN mod 11"/>
   </xsl:when>
   <xsl:otherwise>
      <xsl:variable name="vLen" select="string-length($pN)"/>

      <xsl:variable name="vLen1" select="$vLen -1"/>

      <xsl:variable name="vPart1" select=
          "substring($pN, 1, $vLen1)"/>

      <xsl:variable name="vPart2" select=
          "substring($pN, $vLen1 +1)"/>

      <xsl:variable name="vMod1">
       <xsl:call-template name="mod11">
         <xsl:with-param name="pN" select="$vPart1"/>
       </xsl:call-template>
      </xsl:variable>

      <xsl:variable name="vMod2" select="$vPart2 mod 11"/>

      <xsl:value-of select="(10*$vMod1 + $vMod2) mod 11"/>
   </xsl:otherwise>
  </xsl:choose>
 </xsl:template>
</xsl:stylesheet>
<t>12345678901234567</t>
9
注意事项

  • 此解决方案可以很容易地推广到为任何整数计算
    $n mod$m
    ——只需将
    $m
    作为第二个参数传递即可

  • 另一种泛化方法是将不能使用
    mod
    运算符直接计算的
    $n mod$m
    上限作为参数传递。这在使用XSLT2.0并将
    $n
    作为
    xs:integer
    xs:decimal
    时非常有用

  • 另一种选择是使用Saxon.NET XSLT 2.0处理器或任何其他实现大整数算术的XSLT 2.0处理器。然后,只需使用
    mod
    操作符即可:


  • 这就解释了为什么会发生这种情况,但是有没有办法解决它呢?有一个纯粹的XSLT 1解决这个问题——请看我的答案。然而,当我试图概括它,并用“mod 7”测试它时,当我相信答案是0时,它给出的答案是4。诚然,我可能在对代码进行修改时犯了一个错误,把它概括了。@TimC:我有空的时候会调查一下。@TimC:确实有一个错误。现在已更正,当您仅将11替换为7时,答案现在为0。@m4rc:请注意,我在原始解决方案中发现了一个错误,并已将其修复--答案现在将相应地更新。
    <xsl:stylesheet version="2.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs="http://www.w3.org/2001/XMLSchema">
        <xsl:output omit-xml-declaration="yes" indent="yes"/>
    
     <xsl:template match="/*">
         <xsl:value-of select="xs:integer(.) mod 11"/>
     </xsl:template>
    </xsl:stylesheet>
    
    9