我正在尝试评估一个相当长而复杂的数学表达式,并从python十进制包中得到一些非常奇怪的结果。 (我已经尝试过使用常规花车而且它们没有足够的精度)。这是代码(它有点长,抱歉):
fal_media
以下是我得到的输出:
from decimal import *
def docalc (xi0,yi0,xi1,yi1,xi2,yi2,xi3,yi3,xo0,yo0,xo1,yo1,xo2,yo2,xo3,yo3):
res = (((xi2 * (-yi0 + yi1) + xi1 * (yi0 - yi2) + xi0 * (-yi1 + yi2)) *
((xi2 * (-xo0 + xo1) * yi0 * yi1 + xi1 * (xo0 - xo2) * yi0 * yi2 +
xi0 * (-xo1 + xo2) * yi1 * yi2) *
(xi2 * xi3 * (xo2 - xo3) * yi0 + xi0 * xi3 * (-xo0 + xo3) * yi2 +
xi0 * xi2 * (xo0 - xo2) * yi3) -
(xi1 * xi2 * (-xo1 + xo2) * yi0 + xi0 * xi2 * (xo0 - xo2) * yi1 +
xi0 * xi1 * (-xo0 + xo1) * yi2) *
(xi3 * (xo0 - xo2) * yi0 * yi2 + xi2 * (-xo0 + xo3) * yi0 * yi3 +
xi0 * (xo2 - xo3) * yi2 * yi3)) *
(xi1 * xi2 * (yi0 - yi3) * (yo1 - yo2) +
xi0 * (xi1 * (yi2 - yi3) * (yo0 - yo1) - xi2 * (yi1 - yi3) * (yo0 - yo2) +
xi3 * (yi1 - yi2) * (yo0 - yo3)) - xi1 * xi3 * (yi0 - yi2) * (yo1 - yo3) +
xi2 * xi3 * (yi0 - yi1) * (yo2 - yo3)) +
(-(xi2 * yi0) + xi0 * yi2) * (xi2 * xi3 * (xo2 - xo3) * (yi0 - yi1) +
xi0 * xi3 * (xo0 - xo3) * (yi1 - yi2) +
xi1 * (-(xi3 * (xo1 - xo3) * (yi0 - yi2)) + xi2 * (xo1 - xo2) * (yi0 - yi3) +
xi0 * (xo0 - xo1) * (yi2 - yi3)) - xi0 * xi2 * (xo0 - xo2) * (
yi1 - yi3)) *
((-(xi2 * (-xo0 + xo1) * yi0 * yi1) - xi1 * (xo0 - xo2) * yi0 * yi2 -
xi0 * (-xo1 + xo2) * yi1 * yi2) *
(xi1 * xi2 * (yi0 - yi3) * (yo1 - yo2) +
xi0 * (xi1 * (yi2 - yi3) * (yo0 - yo1) - xi2 * (yi1 - yi3) * (yo0 - yo2) +
xi3 * (yi1 - yi2) * (yo0 - yo3)) -
xi1 * xi3 * (yi0 - yi2) * (yo1 - yo3) + xi2 * xi3 * (yi0 - yi1) * (yo2 - yo3))
- (xi1 * xi2 * (-xo1 + xo2) * yi0 + xi0 * xi2 * (xo0 - xo2) * yi1 +
xi0 * xi1 * (-xo0 + xo1) * yi2) *
(xi1 * yi0 * yi2 * yo0 - xi1 * yi0 * yi3 * yo0 + xi3 * yi0 * yi1 * (yo0 - yo1) -
xi0 * yi1 * yi2 * yo1 + xi0 * yi1 * yi3 * yo1 + xi3 * yi1 * yi2 * (yo1 - yo2) -
xi1 * yi0 * yi2 * yo2 + xi0 * yi1 * yi2 * yo2 - xi0 * yi2 * yi3 * yo2 +
xi1 * yi2 * yi3 * yo2 + xi3 * yi0 * yi2 * (-yo0 + yo2) +
xi2 * yi0 * (yi1 * (-yo0 + yo1) + yi3 * (yo0 - yo3)) + xi1 * yi0 * yi3 * yo3 -
xi0 * yi1 * yi3 * yo3 + xi0 * yi2 * yi3 * yo3 - xi1 * yi2 * yi3 * yo3 +
xi2 * yi1 * yi3 * (-yo1 + yo3)))))
return (res);
def test():
xi0 = 1.1; yi0 = 1.1; xi1 = 2.1; yi1 = 1.1; xi2 = 2.1; yi2 = 2.1; xi3 = 1.1; yi3 = 2.1
xo0 = 91.23; yo0 = 82.34; xo1 = 73.45; yo1 = 64.56; xo2 = 55.67; yo2 = 46.78; xo3 = 37.89; yo3 = 28.90
c_float = docalc(xi0, yi0, xi1, yi1, xi2, yi2, xi3, yi3, xo0, yo0, xo1, yo1, xo2, yo2, xo3, yo3)
getcontext().prec = 19
xi0d = Decimal(xi0); yi0d = Decimal(yi0); xi1d = Decimal(xi1); yi1d = Decimal(yi1); xi2d = Decimal(xi2); yi2d = Decimal(yi2); xi3d = Decimal(xi3); yi3d = Decimal(yi3);
xo0d = Decimal(xo0); yo0d = Decimal(yo0); xo1d = Decimal(xo1); yo1d = Decimal(yo1); xo2d = Decimal(xo2); yo2d = Decimal(yo2); xo3d = Decimal(xo3); yo3d = Decimal(yo3);
c_decimal_19 = docalc(xi0d, yi0d, xi1d, yi1d, xi2d, yi2d, xi3d, yi3d, xo0d, yo0d, xo1d, yo1d, xo2d, yo2d, xo3d, yo3d)
getcontext().prec = 500
xi0d = Decimal(xi0); yi0d = Decimal(yi0); xi1d = Decimal(xi1); yi1d = Decimal(yi1); xi2d = Decimal(xi2); yi2d = Decimal(yi2); xi3d = Decimal(xi3); yi3d = Decimal(yi3);
xo0d = Decimal(xo0); yo0d = Decimal(yo0); xo1d = Decimal(xo1); yo1d = Decimal(yo1); xo2d = Decimal(xo2); yo2d = Decimal(yo2); xo3d = Decimal(xo3); yo3d = Decimal(yo3);
c_decimal_500 = docalc(xi0d, yi0d, xi1d, yi1d, xi2d, yi2d, xi3d, yi3d, xo0d, yo0d, xo1d, yo1d, xo2d, yo2d, xo3d, yo3d)
print("using floats: ",c_float);
print("using Decimals() w/ prec=19: ",c_decimal_19);
print("using Decimals() w/ prec=500: ",c_decimal_500);
test();
为了记录,Mathematica说实际答案是7.80201 * 10 ^ -11。使用具有如此长的复杂表达式的浮点数会导致可怕的舍入错误,我并不感到惊讶,但我很困惑,Decimal()类型(即使精度设置为500)也会返回奇怪的虚假结果。实际上,将精度从19提高到500似乎会导致结果变得更糟。有任何想法吗?这是python小数组包中的错误,或者是python中的一个错误,通常是非常冗长,复杂的数学表达式?感谢。