Фортран имеет свойственные ограничения на числовую точность по сравнению с другими языками?

При работе над простым осуществлением программирования я произвел некоторое время цикл (цикл типа DO в Фортране), который был предназначен для выхода, когда реальная переменная достигла точного значения.

Я заметил, что из-за используемой точности, равенство никогда не встречалось, и цикл стал бесконечным. Это, конечно, не неслыханно, и каждому сообщают, что, вместо того, чтобы сравнить два числа для равенства, это является лучшим, видят, являются ли абсолютной разностью между двумя числами меньше, чем порог набора.

То, что я нашел неутешительным, было то, как низко я должен был установить этот порог, даже с переменными в двойной точности, чтобы мой цикл вышел правильно. Кроме того, когда я переписал "дистиллированную" версию этого цикла в Perl, у меня не было проблем с числовой точностью и циклом штраф, из которого выходят.

Так как код для создания проблемы является настолько маленьким, и в Perl и в Фортране, я хотел бы воспроизвести его здесь в случае, если я заминаю важную деталь:

Код Фортрана

PROGRAM precision_test
IMPLICIT NONE

! Data Dictionary
INTEGER :: count = 0 ! Number of times the loop has iterated
REAL(KIND=8) :: velocity
REAL(KIND=8), PARAMETER :: MACH_2_METERS_PER_SEC = 340.0

velocity = 0.5 * MACH_2_METERS_PER_SEC ! Initial Velocity
DO
        WRITE (*, 300) velocity
        300 FORMAT (F20.8)
        IF (count == 50) EXIT
        IF (velocity == 5.0 * MACH_2_METERS_PER_SEC) EXIT
!       IF (abs(velocity - (5.0 * MACH_2_METERS_PER_SEC)) < 1E-4) EXIT
        velocity = velocity + 0.1 * MACH_2_METERS_PER_SEC
        count = count + 1 
END DO

END PROGRAM precision_test

Код Perl

#! /usr/bin/perl -w
use strict;

my $mach_2_meters_per_sec = 340.0;

my $velocity = 0.5 * $mach_2_meters_per_sec;

while (1) {
        printf "%20.8f\n", $velocity;   
        exit if ($velocity == 5.0 * $mach_2_meters_per_sec);
        $velocity = $velocity + 0.1 * $mach_2_meters_per_sec;
}

Закомментированная строка в Фортране - то, что я должен был бы использовать, чтобы цикл обычно выходил. Заметьте, что порог устанавливается к 1E-4, который я чувствую, довольно вызывает жалость.

Названия переменных происходят от self-study-based, программирующего осуществление, которое я выполнял, и не имейте никакой уместности.

Намерение состоит в том, что цикл останавливается, когда скоростная переменная достигает 1700.

Вот усеченные выводы:

Вывод Perl

    170.00000000
    204.00000000
    238.00000000
    272.00000000
    306.00000000
    340.00000000

...

   1564.00000000
   1598.00000000
   1632.00000000
   1666.00000000
   1700.00000000

Вывод Фортрана

    170.00000000
    204.00000051
    238.00000101
    272.00000152
    306.00000203
    340.00000253

...

   1564.00002077
   1598.00002128
   1632.00002179
   1666.00002229
   1700.00002280

Каковы хороший скорость Фортрана и простота распараллеливания, если его точность воняет? Напоминает мне об этих трех способах сделать вещи:

  1. Правильный путь

  2. Неправильный путь

  3. Питание Max путь

"Это не просто неправильный путь?"

"Да! Но быстрее!"

Все ребячество в стороне, я должен делать что-то не так.

Фортран имеет свойственные ограничения на числовую точность по сравнению с другими языками, или действительно ли я (довольно вероятен) тот в отказе?

Мой компилятор является gfortran (gcc версия 4.1.2), Perl v5.12.1, на Двухъядерном AMD Opteron 1 ГГц.

5
задан EMiller 14 August 2010 в 00:26
поделиться