`
helloyesyes
  • 浏览: 1271100 次
  • 性别: Icon_minigender_2
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

用Oracle PL/SQL 编程实现小数转分数的方法

阅读更多
刚在CNOUG看到有人提问如何用PL/SQL 实现小数转分数的问题,下面这段代码是我的实现,主要思路是将输入的整数及小数都分别取出,然后将小数写成以10的n次方的分数,再求其最大公约数,得到简化的分数,最后将整数及分数合并。代码里有一些处理细节,如负数处理,纯整数处理,纯小数处理等等。
create or replace function dftof(iStr number) return varchar2 as

  --小数转分数

  -- (decimal fraction) to fraction

  --设计人:叶正盛

  v_Str   varchar(50);

  result  varchar(50);

  v_fh    varchar(1); --负数符号

  v_zs    varchar2(20); --整数

  v_xs    varchar2(20); --小数

  v_pos   int; --小数点位置

  v_fm    integer; --分母

  v_fz    integer; --分子

  v_zdgys integer; --最大公约数

  --求最大公约数

  function getZDGYS(iNum1 integer, iNum2 integer) return integer as

    v_ys   integer; --余数

    v_num1 integer;

    v_num2 integer;

  begin

    v_num1 := iNum1;

    v_num2 := iNum2;

    v_ys   := mod(v_num1, v_num2);

    --辗转相除法

    while v_ys <> 0 loop

      v_num1 := v_num2;

      v_num2 := v_ys;

      v_ys   := mod(v_num1, v_num2);

    end loop;

    return v_num2;

  end;

begin

  v_Str := trim(iStr);

  v_pos := instr(v_Str, '.'); --计算小数点位置

  if v_pos = 0 then

    result := v_Str; --纯整数

  else

    if substr(v_Str, 1, 1) = '-' then

      v_zs := substr(v_Str, 2, v_pos - 2); --整数

    else

      v_zs := substr(v_Str, 1, v_pos - 1); --整数

    end if;

    v_xs := substr(v_Str, v_pos + 1); --小数

    if to_number(nvl(v_zs, '0')) = 0 then

      if substr(v_zs, 1, 1) = '-' then

        v_zs := '-'; --如果整数为-0则显示负号

      else

        v_zs := ''; --如果整数为0则不显示整数

      end if;

    else

      v_zs := v_zs || '+'; --整数部份显示样式

    end if;

    v_fz    := to_number(v_xs); --分子

    v_fm    := power(10, length(v_xs)); --分母

    v_zdgys := getZDGYS(v_fm, v_fz); --求最大公约数

    result  := (v_fz / v_zdgys) || '/' || (v_fm / v_zdgys);

    if substr(v_Str, 1, 1) = '-' then

      result := '-(' || v_zs || result || ')';

    else

      result := v_zs || result;

    end if;

  end if;

  return result;

end;
测试结果
Connected to Oracle9i Enterprise Edition Release 9.2.0.7.0 
Connected as yzs
SQL> select dftof(0.4) from dual;

DFTOF(0.4)

--------------------------------------------------------------------------------

2/5

SQL> select dftof(3.4) from dual;

DFTOF(3.4)

--------------------------------------------------------------------------------

3+2/5

SQL> select dftof(-92.25) from dual;

DFTOF(-92.25)

--------------------------------------------------------------------------------

-(92+1/4)

SQL> select dftof(-0.375) from dual;

DFTOF(-0.375)

--------------------------------------------------------------------------------

-(3/8)

SQL> select dftof(-.375) from dual;

DFTOF(-.375)

--------------------------------------------------------------------------------

-(3/8)

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics