Plsql PL/SQL中大数模的计算
我试图用PL/SQL计算大模数。我在这个位置实现了一个方法:在IBAN的模运算下。但是当我使用这个数字时,我得到了错误的结果:22102129011000012345222921210282900128222984 该方法需要这样做: 分段计算D mod 97可以通过多种方式完成。其中一种方法如下: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位数字连接起来,构造一个
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
结尾,而不是您输入的数字