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

原文http://blog.csdn.net/yzsind/archive/2008/07/02/2604798.aspx      感谢作者

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

  1.   
  2.   --小数转分数   
  3.   
  4.   -- (decimal fraction) to fraction   
  5.   
  6.   --设计人:叶正盛   
  7.   
  8.   v_Str   varchar(50);   
  9.   
  10.   result  varchar(50);   
  11.   
  12.   v_fh    varchar(1); --负数符号   
  13.   
  14.   v_zs    varchar2(20); --整数   
  15.   
  16.   v_xs    varchar2(20); --小数   
  17.   
  18.   v_pos   int--小数点位置   
  19.   
  20.   v_fm    integer--分母   
  21.   
  22.   v_fz    integer--分子   
  23.   
  24.   v_zdgys integer--最大公约数   
  25.   
  26.   --求最大公约数   
  27.   
  28.   function getZDGYS(iNum1 integer, iNum2 integerreturn integer as  
  29.   
  30.     v_ys   integer--余数   
  31.   
  32.     v_num1 integer;   
  33.   
  34.     v_num2 integer;   
  35.   
  36.   begin  
  37.   
  38.     v_num1 := iNum1;   
  39.   
  40.     v_num2 := iNum2;   
  41.   
  42.     v_ys   := mod(v_num1, v_num2);   
  43.   
  44.     --辗转相除法   
  45.   
  46.     while v_ys <> 0 loop   
  47.   
  48.       v_num1 := v_num2;   
  49.   
  50.       v_num2 := v_ys;   
  51.   
  52.       v_ys   := mod(v_num1, v_num2);   
  53.   
  54.     end loop;   
  55.   
  56.     return v_num2;   
  57.   
  58.   end;   
  59.   
  60. begin  
  61.   
  62.   v_Str := trim(iStr);   
  63.   
  64.   v_pos := instr(v_Str, &apos;.&apos;); --计算小数点位置   
  65.   
  66.   if v_pos = 0 then  
  67.   
  68.     result := v_Str; --纯整数   
  69.   
  70.   else  
  71.   
  72.     if substr(v_Str, 1, 1) = &apos;-&apos; then  
  73.   
  74.       v_zs := substr(v_Str, 2, v_pos - 2); --整数   
  75.   
  76.     else  
  77.   
  78.       v_zs := substr(v_Str, 1, v_pos - 1); --整数   
  79.   
  80.     end if;   
  81.   
  82.     v_xs := substr(v_Str, v_pos + 1); --小数   
  83.   
  84.     if to_number(nvl(v_zs, &apos;0&apos;)) = 0 then  
  85.   
  86.       if substr(v_zs, 1, 1) = &apos;-&apos; then  
  87.   
  88.         v_zs := &apos;-&apos;--如果整数为-0则显示负号   
  89.   
  90.       else  
  91.   
  92.         v_zs := &apos;&apos;--如果整数为0则不显示整数   
  93.   
  94.       end if;   
  95.   
  96.     else  
  97.   
  98.       v_zs := v_zs || &apos;+&apos;--整数部份显示样式   
  99.   
  100.     end if;   
  101.   
  102.     v_fz    := to_number(v_xs); --分子   
  103.   
  104.     v_fm    := power(10, length(v_xs)); --分母   
  105.   
  106.     v_zdgys := getZDGYS(v_fm, v_fz); --求最大公约数   
  107.   
  108.     result  := (v_fz / v_zdgys) || &apos;/&apos; || (v_fm / v_zdgys);   
  109.   
  110.     if substr(v_Str, 1, 1) = &apos;-&apos; then  
  111.   
  112.       result := &apos;-(&apos; || v_zs || result || &apos;)&apos;;   
  113.   
  114.     else  
  115.   
  116.       result := v_zs || result;   
  117.   
  118.     end if;   
  119.   
  120.   end if;   
  121.   return result;   
  122.   
  123. end;  
  124. 测试结果
    1. Connected to Oracle9i Enterprise Edition Release 9.2.0.7.0    
    2. Connected as yzs   
    3. SQL> select dftof(0.4) from dual;   
    4.   
    5. DFTOF(0.4)   
    6.   
    7. --------------------------------------------------------------------------------   
    8.   
    9. 2/5   
    10.   
    11. SQL> select dftof(3.4) from dual;   
    12.   
    13. DFTOF(3.4)   
    14.   
    15. --------------------------------------------------------------------------------   
    16.   
    17. 3+2/5   
    18.   
    19. SQL> select dftof(-92.25) from dual;   
    20.   
    21. DFTOF(-92.25)   
    22.   
    23. --------------------------------------------------------------------------------   
    24.   
    25. -(92+1/4)   
    26.   
    27. SQL> select dftof(-0.375) from dual;   
    28.   
    29. DFTOF(-0.375)   
    30.   
    31. --------------------------------------------------------------------------------   
    32.   
    33. -(3/8)   
    34.   
    35. SQL> select dftof(-.375) from dual;   
    36.   
    37. DFTOF(-.375)   
    38.   
    39. --------------------------------------------------------------------------------   
    40.   
    41. -(3/8)  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值