循环小数转化为分数

众所周知循环小数是可以转化为分数的。

把循环小数转化为分数一般用极限的方法,比如0.33333........,可以看成是0.3+0.03+0.003+.......这个等比数列的值,然后求等比数列的和,设有n个数,则根据等比数列公式得和为0.3*(1-0.1^n)/(1-0.1),化简得(1-0.1^n)/3,n为无限多个,n趋于无穷大时的极值即为循环小数的值,注意了,这个极值就是循环小数的值,可不是无限接近循环小数的值,举一个特殊的循环小数0.99999.....,值就是1,因为它等于0.3333......乘以3,而0.33333.....等于1/3,1/3*3等于1,所以0.9999......值就是1。由于循环小数的公比肯定小于1,则化简后的等比数列的和,分子和分母一定是可以化为有限小数的,则分子分母都可以变为整数,这也证明了无限循环小数是可以转化为分数的。

观察一下循环小数(括号里为循环体)和分数:

0.33333...... = 3/9;

0.232323...(23) = 23/99

0.2345234523452345....(2345) = 2345/9999

0.1232323....(23) = 122/990

0.12343434...(34) = 1222/9900

……

你是否发现了一些规律,归纳如下:

循环小数0.abbbb......(a表示数字串,可以为空,b表示循环体),a的长度为m,b的长度为n,则化为分数如下:

(ab-a)/(9...)(0...),其中9有n个,0有m个。

0.12345345345...(345) ,则a为12,b为345,ab为12345,m为2,n为3,则化为分数为(12345-12)/99900。

这里使用python3编程实现这个功能,代码如下:

def df2f(n, pos=-1):
    """把小数转换为分数,可以是循环小数,不可以是科学记数法表示的小数
    
    @author: cidplp
    
    @param n:输入小数,可以带整数部分
    @type n:int或者float
    @param pos:小数部分循环位置,从0开始,-1表示不循环
    @type pos:int
    @return:返回分子和分母
    @rtype:int
    """
    
    if isinstance(n, (float, int)) == False:
        print('请输入正确的数字')
        return None
    
    part = str(n) #part是n的字符串样子
    lpart, sep, rpart = part.partition('.') #lpart是整数部分,sep是小数点,rpart是小数部分
    
    if sep == '':
        return int(part), 1
        
        
    if pos >= len(rpart):
        print('循环小数位置错误')
        return None
    
    if pos == -1:
        denominator = int('1'+'0'*len(rpart))
        if int(lpart) >= 0:
            numerator = denominator * int(lpart) + int(rpart)
        else:
            numerator = denominator * int(lpart) - int(rpart)
        return numerator, denominator
    else:
        rlpart = rpart[0: pos] #小数的非循环部分
        rrpart = rpart[pos:] #小数的循环部分
        
        denominator = int('9'*len(rrpart)+'0'*len(rlpart))
        
        if rlpart == '':
            rlpart = '0'
            
        if int(lpart) >= 0:
            numerator = denominator * int(lpart) + int(rpart) - int(rlpart)   
        else:
            numerator = denominator * int(lpart) - int(rpart) + int(rlpart)   
         
        return numerator, denominator
这样算出来的结果不一定是最简的,如果化简的话使用下面函数约分:

def redu(numerator, denominator):
    """分数约分,如果分子分母有小数,则都变为整数后约分
    
    @author: cidplp
    
    @param numerator:分子
    @type numerator:int或float
    @param denominator:分母
    @type denominator:int或float
    @return:约分后分子和分母
    @rtype:int
    """
 
    a = numerator
    b = denominator

    if isinstance(a, (int, float)) == False or isinstance(b, (int, float)) == False:
        print('请输入正确的数字')
        return None
    
    if b == 0:
        print('分母不能为零')
        return None
    
    #把a,b化为分数
    t1 = df2f(a)
    t2 = df2f(b)
    
    #两分数相乘,分子赋值给a,分母赋值给b
    a = t1[0] * t2[1]
    b = t1[1] * t2[0]
    
    #判断a和b是否有负数
    if abs(a+b) == abs(a) + abs(b):
        flag = 1
    else:
        flag = -1

    a = abs(int(a))
    b = abs(int(b))
    
    temp = max(a, b)
    
    i = 2
    while i <= min(a, b):
        if a % i == 0 and b % i == 0:
            a //= i
            b //= i
        else: 
            i += 1
    return a*flag, b



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值