python判断是否是最简分数

Python018

python判断是否是最简分数,第1张

def Is_Simple(a,b):

    if a > b:

        n = a

    else:

        n = b

    for i in range(2,n):

        if a%i == 0 and b%i==0:

            return 0

        else:

            return 1

ostr = raw_input('请输入一个如例子中的分数:2/3')

if '/' in ostr:

    oList = ostr.split('/')

    if oList[0].isnumeric() and oList[1].isnumeric():

        m = int(oList[0])

        d = int(oList[1])

        if Is_Simple(m,d):

            print '%s是最简分数!'% ostr

        else:

            print '%s不是最简分数'% ostr

    else:

        print '请输入正常的分数'

else:

    print '请输入正常的分数'

因为二进制浮点数不能解决这个问题。

先看一个现象,和 round 无关的:

>>>def show(x):

... """打印一个数,20 位精度"""

... print('{:.20f}'.format(x))

...

>>>show(1.5)

1.50000000000000000000

>>>show(1.25)

1.25000000000000000000

>>>show(1.245)

1.24500000000000010658

>>>show(1.45)

1.44999999999999995559

>>>show(1.415)

1.41500000000000003553

从数学上看,一个既约分数(有理数)n/d 要表示为 B 进制数,如果 d 的所有素因子都整除 B,就说明存在一个整数 k,使得分母 d 整除 B^k——比如 q * d = B^k,于是此时有 n/d = n / (B^k / q) = nq / B^k,也就是说 n/d 可以使用至多 k 位数的 B 进制小数有限表示。

反之,也容易证明,如果 d 有素因子不能整数 B,那么就不存在上面的 k,也就是说有理数 n/d 不可能由有限位数的 B 进制数表示。——也就是说会出现循环小数。

对于 10 进制数,所有分母只有素因子 2 和 5 的有理数,都能表示为有限小数。比如 1/2 是 0.5,1/4 是 0.25,1/5 是 0.2,3/8 是 0.375,都是有限的。

而对于 2 进制数,分母里面只有素因子 2 的有理数,才能表示为有限小数。所以 1/2 是 0.1,1/4 是 0.01,3/8 是 0.011。但 1/5 就不能用有限二进制数表示了,是个循环小数 0.0011 0011 0011……。

(什么,你问无理数?小学生都知道无理数是无限不循环小数。)

现在:

计算机的浮点数是用小数表示的。浮点数就是科学计数法,指数部分是个整数,尾数部分是个小数。

计算机的存储是有限的,所以只能使用有限位数的小数表示。

计算机硬件通常是用二进制运算的。

具体到 Python 的 float,C/C++ 的 float/double,都是有限长度的、二进制、浮点数。准确地说,是这个:IEEE floating point

现在问题来了。人写程序用十进制数,计算机运行程序用二进制数,怎么办?转换呗。

从概念上说,就是我写:

a(10) = 0.5

计算机读:

a(2) = 0.1

我写:

b(10) = 0.375

计算机读

b(2) = 0.011

可如果我写

c(10) = 0.2

计算机就只能读成了有限位数,比如 12 位:

c(2) = 0.0011 0011 0011(咔嚓切断)

其实这个被截断保留 12 位二制制位的数用十进制表示是 0.199951171875,已经不准了。你说不对呀这个小了,最后一位能不能加上去,让计算机读成

c(2) = 0.0011 0011 0100(进了一位)

这个数用十进制表示则是 0.2001953125,又大了。

——实际的计算机中,python 的 float 是用 64 位浮点数,其中 53 位是尾数部分,误差小得多了,但还是不可能没有。

所以,计算机在把人写的程序转换为内部代码的时候,就必须做十进制到二进制的转换。这个转换就已经不得不带来误差了。当然,像前面说的,不是所有的数都有误差,0.5、3.75、78.625 都不会有误差,但简单的 0.2、3.15 就会有进制转换误差。

所以,在开始计算 round 这个四舍五入的函数之前,在程序刚被读入计算机时,这个变量的值早已经不精确了。round 又能解决什么问题?

话说回来,round 本身在一些情况下是准确的。比如 0.5、1.5、2.5、3.5 这些数,都能用有限位二进制数表示,它们直接 round 的结果也都是准确的,不过使用的不是四舍五入而是无偏算法(把 0.5 向偶数而不是向上舍入,这里指 Python 3)。round 在另一些情况下又可能是不准确的,因为 Python 的 round 有两个参数,第二个参数表示舍入到第几位,就需要对原数先计算再舍入,就不准确了。

如果让 Python 减慢速度,也在内部用十进制表示和计算,就不会出现进制转换和移位这种来源的舍入误差,此时做舍入运算或输入输出就是精确的了。虽然这不能防止其他计算(比如除法、三角函数)带来的误差,但在一些场合,比如金融算钱的时候,还是非常有用的。在 Python 里面可以用 decimal 包来使用十进制浮点数,避免输入输出的带来的进制转换误差,按十进制移位时除法带来的误差等。

小结:

误差主要来自输入时十进制转换为计算机内部二进制时,且这个问题在有限精度下不可能解决,也不需要解决。

round 可以准确舍入,但它涉及的移位计算也可能带来其他误差。

Python 的 decimal 包可用于解决这一问题。

round()如果只有一个数作为参数,不指定位数的时候,返回的是一个整数,而且是最靠近的整数(这点上类似四舍五入)。但是当出现.5的时候,两边的距离都一样,round()取靠近的偶数,这就是为什么round(2.5) = 2。当指定取舍的小数点位数的时候,一般情况也是使用四舍五入的规则,但是碰到.5的这样情况,如果要取舍的位数前的小树是奇数,则直接舍弃,如果偶数这向上取舍。

计算机二级考试中Python科目不难,下点功夫是容易过的。Python编程语言相较于其他编程语言更简单更容易理解,Python语言相当于是一种辅助语言,现在普遍使用的是Python3.10版本,属于进阶版,其更具兼容性,和方便性。掌握Python编程的基础上加深了解,更有利于我们通过Python考试科目。

可以将学习Python编程基础。将其分作几个板块进行学习了解,例如了解基本的语法元素,了解编程基本数据类型,了解程序的控制结构,关于函数和代码运用,了解数据的类型等等。将Python基础区域化,更有利于我们掌握和记住编程的相关知识。学习理论往往是不够的,更需要的是实际操作。从编写简单程序,例如建立一个文档在通过代码来执行,绘制一个小乌龟,这样更能让我们熟悉编写过程,能够增加熟练度。灵活记忆和运用基础的语法要素,就能更好的巩固基础,避免一个小细节而导致的错误。

Python题型与分值的分布为,选择题一题一分总40题,基本操作题总18分,简单应用题总24分,综合题18分一般是两个题分值占比较高。满分100及格分为60分,选择题和基本操作题比较容易拿分,比如多记忆知识点,多练练题,注意细节,就不会在容易拿分的题型上失分,达到及格就很容易。多看一些编程案例,更有利于增强我们在答题过程中的题型印象减少错误。例如常考点基本语法要素,大写字母,小写字母,数字,下划线,汉字组成;但首字符不能是数字,一个变量名中间不能出现空格,33个关键字不能作为变量名。几乎全部都会每个题都会用到。