在撰寫一段程式時要用到已知有理數,求表示該有理數的兩個相除整數.下面是程式,有問題和建議可以交流探討,不足之處還請大家指出.
import math as mt
import re
def Ftoints(x:float)->tuple:
if abs(x)==0:
return 0,1
kk=1 if x>0 else -1
ss=str(abs(x))
dotloc=ss.find(".")
if dotloc==-1:
return int(x),1
sst=re.findall(r'\.[0-9]*?([0-9]{1,})\1+[0-9]?$',ss)
if len(sst)>0:
ssloc=ss.find(sst[0])
a=int(sst[0])
b=int((10**len(sst[0])-1)*10**(ssloc-dotloc-1))
c=mt.gcd(a,b)
a=a//c;b=b//c
ssk=ss[:ssloc]
dd,ee=Ftoints(float(ssk))
a=int(a*ee+b*dd)
b=int(b*ee)
else:
b=int(10**(len(ss)-dotloc-1))
a=int(abs(x)*b)
c=mt.gcd(a,b)
a=a//c;b=b//c
return kk*a,b
if __name__=="__main__":
print(Ftoints(-3.66666667))
#Out: (-11, 3)
uj5u.com熱心網友回復:
print(Ftoints(-0.0001))print(Ftoints(-0.000000001))
uj5u.com熱心網友回復:
改進了一下,format的f格式默認精度為6,只能處理低于這個精度的,否則增加精度別的正常資料也無法處理(因為精度拓寬后全加0)
import math as mt
import re
def Ftoints(x:float)->tuple:
if mt.isclose(abs(x),0,rel_tol=1e-9,abs_tol=1e-9):
return 0,1
kk=1 if x>0 else -1
ss="{:f}".format(abs(x))
dotloc=ss.find(".")
if dotloc==-1:
return int(x),1
sst=re.findall(r'\.[0-9]*?([0-9]{1,})\1+[0-9]?$',ss)
if len(sst)>0 and int(sst[0])!=0:
ssloc=ss.find(sst[0])
a=int(sst[0])
b=int((10**len(sst[0])-1)*10**(ssloc-dotloc-1))
c=mt.gcd(a,b)
if c!=0:
a=a//c;b=b//c
ssk=ss[:ssloc]
dd,ee=Ftoints(float(ssk))
a=int(a*ee+b*dd)
b=int(b*ee)
else:
b=int(10**(len(ss)-dotloc-1))
a=int(abs(x)*b)
c=mt.gcd(a,b)
if c!=0:
a=a//c;b=b//c
return kk*a,b
if __name__=="__main__":
print(Ftoints(-3.66666667))
#Out: (-11, 3)
uj5u.com熱心網友回復:
print(Ftoints(-.2334334334))uj5u.com熱心網友回復:
又修改了一下,歡迎挑錯,把精度設為了15,太高時輸入的資料和最終存盤的也不一樣.程式如下:
import math as mt
import re
def Ftoints(x:float)->tuple:
if mt.isclose(abs(x),0,rel_tol=1e-15,abs_tol=1e-15):
return 0,1
kk=1 if x>0 else -1
ss="{:<0.15f}".format(abs(x))
dotloc=ss.find(".")
if dotloc==-1:
return int(x),1
sst=re.findall(r'\.[0-9]*?([0-9]{1,})\1+[1-9]?[0]+$',ss)
if len(sst)>0 and int(sst[0])!=0:
ssloc=ss.find(sst[0])
a=int(sst[0])
b=int((10**len(sst[0])-1)*10**(ssloc-dotloc-1))
c=mt.gcd(a,b)
if c!=0:
a=a//c;b=b//c
ssk=ss[:ssloc]
dd,ee=Ftoints(float(ssk))
a=round(a*ee+b*dd)
b=round(b*ee)
else:
sk=re.findall(r'[0]+$',ss)
tt=len(ss) if len(sk)<=0 else ss.rfind(sk[0])
b=round(10**(tt-dotloc-1))
a=round(abs(x)*b)
c=mt.gcd(a,b)
if c!=0:
a=a//c;b=b//c
return kk*a,b
if __name__=="__main__":
print(Ftoints(-0.01))
print(Ftoints(-0.000000001))
print(Ftoints(-.2334334334))
print(Ftoints(1.001))
print(Ftoints(-0.003333333))
print(Ftoints(-0.12666666667))
#Out:
(-1, 100)
(-1, 1000000000)
(-1166, 4995)
(1001, 1000)
(-1, 300)
(-19, 150)
uj5u.com熱心網友回復:
一個小錯誤,把上面程式這一行?[0]+$改為?[0]*$sst=re.findall(r'\.[0-9]*?([0-9]{1,})\1+[1-9]?[0]+$',ss)
改為
sst=re.findall(r'\.[0-9]*?([0-9]{1,})\1+[1-9]?[0]*$',ss)
uj5u.com熱心網友回復:
最終是這樣的
def Ftoints(x:float)->tuple:
if mt.isclose(abs(x),0,rel_tol=1e-15,abs_tol=1e-15):
return 0,1
kk=1 if x>0 else -1
ss="{:<0.15f}".format(abs(x))
dotloc=ss.find(".")
if dotloc==-1:
return round(x),1
sst=re.findall(r'\.[0-9]*?([0-9]{1,})\1+[1-9]?[0]*$',ss)
if len(sst)>0 and int(sst[0])!=0:
ssloc=ss.find(sst[0])
a=int(sst[0])
b=round((10**len(sst[0])-1)*10**(ssloc-dotloc-1))
c=mt.gcd(a,b)
if c!=0:
a=a//c;b=b//c
ssk=ss[:ssloc]
dd,ee=Ftoints(float(ssk))
a=round(a*ee+b*dd)
b=round(b*ee)
else:
sk=re.findall(r'[0]+$',ss)
tt=len(ss) if len(sk)<=0 else ss.rfind(sk[0])
b=round(10**(tt-dotloc-1))
a=round(abs(x)*b)
c=mt.gcd(a,b)
if c!=0:
a=a//c;b=b//c
return kk*a,b
uj5u.com熱心網友回復:
Ftoints(-0.22334334334)uj5u.com熱心網友回復:
二次迭代又有重復的數字惹的禍,下面的程式去掉了二次迭代。歡迎繼續挑錯,改后的程式如下:
import math as mt
import re
def Ftoints(x:float)->tuple:
if mt.isclose(abs(x),0,rel_tol=1e-15,abs_tol=1e-15):
return 0,1
kk=1 if x>0 else -1
ss="{:<0.15f}".format(abs(x))
dotloc=ss.find(".")
if dotloc==-1:
return round(x),1
sst=re.findall(r'\.[0-9]*?([0-9]{1,})\1+[1-9]?[0]*$',ss)
if len(sst)>0 and int(sst[0])!=0:
ssloc=ss.find(sst[0])
a=int(sst[0]); b=round((10**len(sst[0])-1)*10**(ssloc-dotloc-1))
c=mt.gcd(a,b)
if c!=0:
a=a//c;b=b//c
ssk=ss[:ssloc]
sk=re.findall(r'[0]+$',ssk)
tt=len(ssk) if len(sk)<=0 else ssk.rfind(sk[0])
ee=round(10**(tt-dotloc-1)); dd=round(abs(float(ssk))*ee)
c=mt.gcd(dd,ee)
if c!=0:
dd=dd//c;ee=ee//c
a=round(a*ee+b*dd); b=round(b*ee)
else:
sk=re.findall(r'[0]+$',ss)
tt=len(ss) if len(sk)<=0 else ss.rfind(sk[0])
b=round(10**(tt-dotloc-1)); a=round(abs(x)*b)
c=mt.gcd(a,b)
if c!=0:
a=a//c;b=b//c
return kk*a,b
if __name__=="__main__":
print(Ftoints(-3.11454))
print(Ftoints(-0.000000001))
print(Ftoints(-.2334334334))
print(Ftoints(1.3333333333333333333333333333333))
print(Ftoints(2.666666666666666666666666666666666666666666666666666667))
print(Ftoints(-0.003333333))
print(Ftoints(-0.12666666667))
print(Ftoints(-0.22334334334))
print(Ftoints(6/5))
print(Ftoints(1.15156666666667e-3))
#Out:
(-155727, 50000)
(-1, 1000000000)
(-1166, 4995)
(4, 3)
(8, 3)
(-1, 300)
(-19, 150)
(-5578, 24975)
(6, 5)
(34547, 30000000)
uj5u.com熱心網友回復:
1.非回圈小數,a=原數*10^小數點后位數 b=10^小數點后位數2.如果你要把有重復的小數看成回圈小數,那就看你人為規定多少個回圈節算作回圈小數
3.回圈小數化分數有現成公式
a = int(原數*10^(回圈節起始位置-小數點位置-1+回圈節長度))-int(原數*10^(回圈節起始位置-小數點位置-1))
b = 10^(回圈節起始位置-小數點位置-1+回圈節長度)-10^(回圈節起始位置-小數點位置-1)
4.分別除以gcd(a,b)即可,按道理,你給的數都是非回圈小數
uj5u.com熱心網友回復:
sst=re.findall(r'\.[0-9]*?([0-9]{1,})\1+[1-9]?[0]*$',ss)想控制有多少個回圈節如兩個做為回圈小數可改成如下,
sst=re.findall(r'\.[0-9]*?([0-9]{1,})\1{2,}[1-9]?[0]*$',ss)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/10209.html
上一篇:漏洞掃描
下一篇:紙張對折計算
