使用Fortran进行两条线交叉的数值精度

时间:2017-03-26 13:55:47

标签: floating-point fortran precision

我想找到两条线的交点,然后然后检查该点是否等于预定义的值(这里我把它当作确切的值)。

Problem schematic

这是我的最低工作范例,

PROGRAM foo
    IMPLICIT NONE

    ! Real kind number
    INTEGER, PARAMETER :: RKN = 8

    ! Parameters of line formulae
    REAL(RKN) :: a1, b1, c1, a2, b2, c2

    ! Exact values
    REAL(RKN), DIMENSION(2) :: ans

    ! Points of first line
    REAL(RKN), DIMENSION(2) :: pnt_a, pnt_b

    ! Slope of first line
    REAL(RKN) :: m

    ! Intersection
    REAL(RKN), DIMENSION(2) :: x

    ! Output format
    CHARACTER(*), PARAMETER :: fmt = '(X, A, X, GO)'

    pnt_a = [- 4._RKN, - 1._RKN]
    pnt_b = [- 1._RKN ,  0._RKN]

    m = (pnt_b(2) - pnt_a(2)) / (pnt_b(1) - pnt_a(1))

    a1 = m
    b1 = - 1._RKN
    c1 = m * pnt_a(1) - pnt_a(2)

    ! Second line is horizontal and has no vertical intercept
    a2 =   0._RKN
    b2 =   1._RKN
    c2 =   0._RKN

    ! Cramer's rule
    x = [(c1 * b2 - b1 * c2) / (a1 * b2 - b1 * a2), (a1 * c2 - c1 * a2) / (a1 * b2 - b1 * a2)]

    ans = [- 1._RKN, 0._RKN]

    WRITE(*, fmt) 'x(1)   = ', x(1)
    WRITE(*, fmt) 'ans(1) = ', ans(1)
    PRINT *, x(1) == ans(1)
    PRINT *, ABS(x(1) - ans(1)) < EPSILON(1._RKN)

END PROGRAM

编译后,输出为,

x(1)   =     -.9999999999999998
ans(1) =     -1.000000000000000
F
F

虽然实数是双精度,但输出并不足以接近确切答案,即使使用EPSILON()内在函数也是如此。如果RKN设置为16,则会生成

x(1)   =    -1.00000000000000000000000000000000
ans(1) =    -1.00000000000000000000000000000000
F
F

我该如何处理这类问题?

0 个答案:

没有答案