如何判断一个数是不是有理数的平方
请教各位朋友,如何在python中判断一个数是不是任意有理数的平方呢? 数学中怎么判断,它就怎么判断。 本帖最后由 Judie 于 2020-1-11 19:39 编辑emmmm,这样子?
import math
while True:
n = float(input()) #接受用户输入 赋值n
a = math.sqrt(n) #取n的平方根 赋值a
b = a*a #取(n的平方根)的平方 赋值b
if b == n: #判断(n的平方根)的平方是否等于n 即 b是否等于n
print('是',a,'的平方')#等于则是
else:
print('不是')#不等于则不是
#有理数是整数(正整数、0、负整数)和分数的统称,是整数和分数的集合。
#整数也可看做是分母为一的分数。
#不是有理数的实数称为无理数,即无理数的小数部分是无限不循环的数。
#应该就是这样子的吧~
#可能不是很完美,但感觉运行上去还可的样子 Judie 发表于 2020-1-12 02:51
emmmm,这样子?
开平方根后取整再乘方看是否相等
这个开平方根可用系统函数,也可自己写 Judie 发表于 2020-1-12 02:51
emmmm,这样子?
回错了,以为你是楼主 wp231957 发表于 2020-1-11 18:42
开平方根后取整再乘方看是否相等
这个开平方根可用系统函数,也可自己写
嗯,我的思路就是这样
能帮我看看我的code对不对吗? Judie 发表于 2020-1-12 02:51
emmmm,这样子?
float(input()) ** 0.5 zltzlt 发表于 2020-1-11 19:48
哦!然后这样就相当于取代了sqrt那步是么?也不用import math了?! Judie 发表于 2020-1-12 10:01
哦!然后这样就相当于取代了sqrt那步是么?也不用import math了?!
是。因为一个数的平方根 = 那个数 ^ (1 / 2),一个数的立方根 = 那个数 ^ (1 / 3),以此类推。
例如:
>>> 8 ** (1 / 3)
2.0 zltzlt 发表于 2020-1-11 21:03
是。因为一个数的平方根 = 那个数 ^ (1 / 2),一个数的立方根 = 那个数 ^ (1 / 3),以此类推。
例如 ...
数学使人头秃。
{:10_269:} 本帖最后由 Croper 于 2020-1-12 14:22 编辑
恩。。。楼主说的是一个数,是不是任意有理数的平方。
那么也包括浮点数。
所以开方取整再平方的做法肯定是不对的
另一方面,平常使用的float,在python内部存储时也是使用的二进制方式。
而二进制的小数是无法正确表示大部分十进制的小数的,
比如十进制的1.1,以二进制表示,则为1.00011001100110011001...的无限循环小数。
所以,大部分float也是经过了近似处理的,
对于1.21这种,其虽然是1.1的平方,但是:
n=1.1
a=sqrt(n)
b=n**0.5
print(a**2)#等于1.2100000000000002
print(b**2)#等于1.2100000000000002
因为浮点数取近似的关系,也不能做到完全正确
所以,开方再平方的做法也不能取得正确的结果。
既然以上已经说到,大部分float在计算机内部并不能精确存储。
而要精确存储一个有理数,最好的方法就是使用分数,
那么这个问题就转化成了:找到一个最接近float的,(比较简单的)分数。
比如0.3333333333能划为1/3
0.142857142857能划为1/7
1.21能划为121/100
python是自带一个分数库fractions的,但是其把小数划为分数的能力有点惨不忍睹:
from fractions import Fraction
a=Fraction(1.21)
print(a) #输出1362338887279575/1125899906842624
这似乎把1.21对应的2进制近似值转化成了分数。
要解决这个问题,可以使用连分数法:
https://baike.baidu.com/item/%E8%BF%9E%E5%88%86%E6%95%B0/2715871?fr=aladdin
下面是我写的一个使用连分数法把小数划为分数的代码:
def float2fraction(n):
stk=[]
for i in range(10):
a=int(round(n))
stk.append(a)
if (abs(n-a)<0.00001): break
n=1/(n-a)
num=0
den=1
for i in reversed(stk):
num,den=den,num+i*den
num,den=den,num
return fractions.Fraction(num,den)
最多连分10次,并且当某一次结果的剩下的绝对值小于0.00001时停止迭代
来试一试这个函数:print(float2fraction(0.1))#输出1/10
print(float2fraction(1.21)) #输出121/100
print(float2fraction(0.1111111111111)) #1/9
能划为分数之后剩下的问题就简单多了,只要分子和分母都是完全平方数就说明这个有理数是另一个有理数的平方:def isSquareNum(n:int):
if (isinstance(n,int)):
return int(n**0.5)**2==n
f=float2fraction(n)
return isSquareNum(f.numerator) and isSquareNum(f.denominator)
测试:print(isSquareNum(2)) #FALSE
print(isSquareNum(4)) #TRUE
print(isSquareNum(0.1)) #FALSE
print(isSquareNum(0.01))#TRUE
print(isSquareNum(1.44))#TRUE
print(isSquareNum(1.444))#FALSE
基本符合要求
当然,因为无法取得float的精确值,所以每种做法都是有缺陷的。这是我觉得缺陷比较小的做法,对于某些特定值,肯定也是会出错的。
Croper 发表于 2020-1-12 14:20
恩。。。楼主说的是一个数,是不是任意有理数的平方。
那么也包括浮点数。
所以开方取整再平方的做法肯定 ...
非常非常感谢您的耐心解答,最近一直没有上线。问题的确就是您说的那个意思,您的解答我还要慢慢学习哦{:9_228:}
页:
[1]