dar*_*ude 2 python floating-point decimal floating-accuracy
我似乎在漂浮物上失去了很多精确度.
例如,我需要解决一个矩阵:
4.0x -2.0y 1.0z =11.0
1.0x +5.0y -3.0z =-6.0
2.0x +2.0y +5.0z =7.0
Run Code Online (Sandbox Code Playgroud)
这是我用来从文本文件导入矩阵的代码:
f = open('gauss.dat')
lines = f.readlines()
f.close()
j=0
for line in lines:
bits = string.split(line, ',')
s=[]
for i in range(len(bits)):
if (i!= len(bits)-1):
s.append(float(bits[i]))
#print s[i]
b.append(s)
y.append(float(bits[len(bits)-1]))
Run Code Online (Sandbox Code Playgroud)
我需要使用gauss-seidel解决,所以我需要重新排列x,y和z的方程式:
x=(11+2y-1z)/4
y=(-6-x+3z)/5
z=(7-2x-2y)/7
Run Code Online (Sandbox Code Playgroud)
这是我用来重新排列方程的代码.b
是系数矩阵,y
是答案向量:
def equations(b,y):
i=0
eqn=[]
row=[]
while(i<len(b)):
j=0
row=[]
while(j<len(b)):
if(i==j):
row.append(y[i]/b[i][i])
else:
row.append(-b[i][j]/b[i][i])
j=j+1
eqn.append(row)
i=i+1
return eqn
Run Code Online (Sandbox Code Playgroud)
然而,我得到的答案并不精确到小数位.
例如,在重新排列上面的第二个等式时,我应该得到:
y=-1.2-.2x+.6z
Run Code Online (Sandbox Code Playgroud)
我得到的是:
y=-1.2-0.20000000000000001x+0.59999999999999998z
Run Code Online (Sandbox Code Playgroud)
这似乎不是一个大问题,但是当你将数字提高到一个非常高的功率时,错误是非常大的.有没有解决的办法?我尝试了这个Decimal
课程,但是它在功能方面效果不佳(即Decimal(x)**2
).
有任何想法吗?
Dou*_*rie 14
IEEE浮点是二进制,而不是十进制.没有固定长度的二进制分数恰好为0.1或其任何倍数.它是一个重复的分数,如十进制的1/3.
除了Decimal类之外的其他选项是
使用Common Lisp或Python 2.6或其他语言具有精确的有理数
使用例如frap将双打转换为接近的有理数
小智 11
我不太熟悉Decimal类来帮助你,但你的问题是由于十进制分数通常不能用二进制精确表示的事实,所以你看到的是最接近的可能近似值; 没有使用特殊类(如Decimal,可能),没有办法避免这个问题.
EDIT:
十进制类怎么办不适合你呢?只要我从字符串开始,而不是浮动,权力似乎工作正常.
>>> import decimal
>>> print(decimal.Decimal("1.2") ** 2)
1.44
Run Code Online (Sandbox Code Playgroud)
该模块文档解释了需要和使用decimal.Decimal
非常清楚,你应该检查出来,如果你还没有.