Plsql PL/SQL中大数模的计算

Plsql PL/SQL中大数模的计算,plsql,modulus,Plsql,Modulus,我试图用PL/SQL计算大模数。我在这个位置实现了一个方法:在IBAN的模运算下。但是当我使用这个数字时,我得到了错误的结果:22102129011000012345222921210282900128222984 该方法需要这样做: 分段计算D mod 97可以通过多种方式完成。其中一种方法如下: 从D最左边的数字开始,用前9位数字构造一个数字,并称之为N 计算N模97。如果结果小于10,则在结果前加上0,给出范围为00到96的结果 通过将上述结果(步骤2)与D的后续7位数字连接起来,构造一个

我试图用PL/SQL计算大模数。我在这个位置实现了一个方法:在IBAN的模运算下。但是当我使用这个数字时,我得到了错误的结果:22102129011000012345222921210282900128222984

该方法需要这样做:

分段计算D mod 97可以通过多种方式完成。其中一种方法如下:

  • 从D最左边的数字开始,用前9位数字构造一个数字,并称之为N
  • 计算N模97。如果结果小于10,则在结果前加上0,给出范围为00到96的结果
  • 通过将上述结果(步骤2)与D的后续7位数字连接起来,构造一个新的9位N。如果D中剩余的数字少于7位,但至少有一位,则根据上述结果(步骤2)和D的后续数字,构造一个新的N,该N将少于9位
  • 重复步骤2-3,直到处理完D的所有数字
  • 步骤2中的最终计算结果为D mod 97=N mod 97

    我做了一些日志记录,这些是所有模步骤的结果:

    221021290110000123452229211210282900128222984 (221021290 % 97 = 0)
    00110000123452229211210282900128000000 (001100001 % 97 = 21)
    2123452229211210282900128000000 (212345222 & 97 = 0)
    009211210282900128000000 (009211210 % 97 = 90)
    90282900128000000 (902829001 % 97 = 46)
    4628000000 (462800000 % 97 = 2)
    020 = 20
    
    结果必须是1。我用模计算器检查它,它需要是1。对于大多数数字,计算器是正确的

    这是我写的代码,怎么可能这个数字不正确:

    create or replace function doubleDiget (iban number)
    return varchar2
    as
    begin
      if(iban <= 9) then
        return concat('0',iban);
      else
        return iban;
      end if;
    end doubleDiget;
    
    create or replace FUNCTION modbig (iban number)   
        RETURN varchar2                     
          AS  
          lengthIban number(38);
          modUitkomts number(38);
          modUitkomtsc varchar(38);
          restIban varchar(38);
          modlength number(38);
      BEGIN
    
      modUitkomts := SUBSTR(iban,0,9) mod 97;
      modUitkomtsc := doubleDiget(modUitkomts);
      restIban := concat(modUitkomtsc,SUBSTR(iban,10)); 
      dbms_output.put_line(restIban);
    
      loop
        if( length(restIban) >= 9) then
            modUitkomts := SUBSTR(restIban,0,9) mod 97;
            modUitkomtsc := doubleDiget(modUitkomts);
            restIban := concat(modUitkomtsc,SUBSTR(restIban,10)); 
            dbms_output.put_line(restIban);
        else
          exit;
        end if;
      end loop;
    
      modUitkomts := restIban mod 97;
      return modUitkomts;
    
    
    END modbig;
    
    begin
    DBMS_OUTPUT.PUT_LINE(modbig(221021290110000123452229211210282900128222984));  
    end;
    
    创建或替换函数doubleDiget(iban编号)
    返回varchar2
    作为
    开始
    如果(iban=9),则
    modUitkomts:=SUBSTR(restIban,0,9)mod 97;
    modUitkomtsc:=双数字(modUitkomts);
    restIban:=concat(modUitkomtsc,SUBSTR(restIban,10));
    dbms_output.put_line(restIban);
    其他的
    出口
    如果结束;
    端环;
    modUitkomts:=restIban mod 97;
    返回模式;
    末模大;
    开始
    DBMS_OUTPUT.PUT_LINE(modbig(22102129011000012345222921210282900128222984));
    结束;
    
    使用
    VARCHAR2
    代替
    NUMBER

    SQL> DECLARE
      2     FUNCTION modbig(iban VARCHAR2) RETURN VARCHAR2 IS -- won't be rounded
      3        lengthIban   NUMBER(38);
      4        modUitkomts  NUMBER(38);
      5        modUitkomtsc VARCHAR(38);
      6        restIban     VARCHAR(50);
      7        modlength    NUMBER(38);
      8     BEGIN
      9        restIban     := iban;
     10        modUitkomts  := SUBSTR(restIban, 0, 9) MOD 97;
     11        modUitkomtsc := LPAD(modUitkomts, 2, '0');
     12        restIban := concat(modUitkomtsc, SUBSTR(iban, 10));
     13  
     14        LOOP
     15           IF (length(restIban) >= 9) THEN
     16              modUitkomts  := SUBSTR(restIban, 0, 9) MOD 97;
     17              modUitkomtsc := LPAD(modUitkomts, 2, '0');
     18              restIban := concat(modUitkomtsc, SUBSTR(restIban, 10));
     19           ELSE
     20              EXIT;
     21           END IF;
     22        END LOOP;
     23        modUitkomts := restIban MOD 97;
     24        RETURN modUitkomts;
     25     END modbig;
     26  
     27  BEGIN
     28     DBMS_OUTPUT.PUT_LINE(
     29        modbig('221021290110000123452229211210282900128222984')); -- varchar2
     30  END;
     31  /
    1
    PL/SQL procedure successfully completed
    
    说明:
    数字
    数据类型的精度约为38位,因此对于非常大的数字,将对其进行四舍五入,因此您的输出以
    0000
    结尾,而不是您输入的数字