FUNCTION FBIG(N NUMBER) RETURN NUMBER
IS
R NUMBER;
M NUMBER;
S NUMBER;
BEGIN
M := N;
WHILE M>0 LOOP
R := MOD(M,10);
M := FLOOR(M/10);
S := GREATEST(R,M);
END LOOP;
RETURN S;
END FBIG;
END;
/
EXEC DBMS_OUTPUT.PUT_LINE(FBIG(47839));
如果47839. 9是输入值,则找到最大数字。我试图通过MOD获取最后一位数字并通过FLOOR删除小数。
答案 0 :(得分:2)
只需将数字转换为PL / SQL中的字符串并测试每个字符,直到达到小数点:
CREATE FUNCTION FBIG(N NUMBER) RETURN NUMBER
IS
s CONSTANT VARCHAR2(4000) := TO_CHAR( n );
c CHAR(1);
m CHAR(1) := NULL;
BEGIN
FOR i IN 1 .. LENGTH( s ) LOOP
c := SUBSTR( s, i, 1 );
IF c = '.' THEN
EXIT;
ELSIF m IS NULL OR c > m THEN
m := c;
END IF;
END LOOP;
RETURN TO_NUMBER( m );
END FBIG;
/
为什么你的功能不起作用:
M := N;
WHILE M>0 LOOP
R := MOD(M,10);
M := FLOOR(M/10);
S := GREATEST(R,M);
END LOOP;
您正在使用每个循环覆盖S
,因此返回值将仅考虑最重要的数字,因为之前的数字将被覆盖。因此,对于N = 47839.9
,它所经历的步骤是:
R = 9.9, M = 4783, S = 4783
R = 3, M = 478, S = 478
R = 8, M = 47, S = 47
R = 7, M = 4, S = 7
R = 4, M = 0, S = 4
然后它将返回4
。
如何修复您的功能:
CREATE FUNCTION FBIG(N NUMBER) RETURN NUMBER
IS
s NUMBER(1,0) := NULL;
r NUMBER(1,0) := NULL;
m NUMBER := FLOOR( ABS( n ) );
BEGIN
WHILE m > 0 LOOP
r := MOD( m, 10 );
IF s IS NULL OR r > s THEN
s := r;
END IF;
m := ( m - r ) / 10;
END LOOP;
RETURN s;
END FBIG;
/
答案 1 :(得分:2)
你的原始代码不起作用的原因是因为a)你的M总是大于或等于R直到最后一个循环(当M变为0时),以及b)你没有比较当前的值为S的前一个值。
您的代码可以调整为按以下方式工作:
FUNCTION fbig(n NUMBER) RETURN NUMBER IS
r NUMBER;
m NUMBER;
s NUMBER := 0;
BEGIN
m := n;
WHILE m > 0
LOOP
r := MOD(m, 10);
m := floor(m / 10);
s := greatest(r, s);
END LOOP;
RETURN s;
END fbig;
/
我只需要进行两项更改,更改最大值以在s和r之间进行检查,并在开始时向右分配0(否则s将始终为null,无论r的值如何)。
答案 2 :(得分:1)
另一种方法怎么样?将数字拆分为数字并选择其中最大的数字:
SQL> create or replace function fbig (n number)
2 return number
3 is
4 retval number;
5 begin
6 select max(num)
7 into retval
8 from (select substr(to_char(n), level, 1) num
9 from dual
10 connect by level <= length(n)
11 );
12
13 return retval;
14 end;
15 /
Function created.
SQL> select fbig(47839) res1,
2 fbig(125.774) res2
3 from dual;
RES1 RES2
---------- ----------
9 7
SQL>