C ошибка двойной суммы - PullRequest
1 голос
/ 17 июня 2011


Кто-нибудь может объяснить мне, почему выполнение этой программы становится невозможным, если?
Я знаю существование проблем точности с double и float, но я не могу понять проблему в этом примере ..

Заранее спасибо!

NB. Я скомпилировал его под Ubuntu 10.10 с GCC 4.4.5

#include <stdio.h>

#define NUM_JOINTS 1

typedef struct {
    double t1;
    double t2;
    double t3;
} jointProfile;

jointProfile jp[NUM_JOINTS];

int main() {
    jp[0].t1 = 0.51639777949432230652604403076111339032649993896484375;
    jp[0].t2 = 0.00000000000000000000000000000000000000000000000000000;
    jp[0].t3 = 0.77459666924148340427791481488384306430816650390625000;

    double maxTime = (jp[0].t1 + jp[0].t2 + jp[0].t3);

    if ((jp[0].t1 + jp[0].t2 + jp[0].t3) < maxTime) {
        printf("Infeasible\n");
    }

    return 0;
}

Ответы [ 3 ]

2 голосов
/ 17 июня 2011

Вот что говорит C FAQ :

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

Поэтому, если вы не уверены, где ваш компилятор хранит значения, вы не можете быть уверены в результате.

2 голосов
/ 17 июня 2011

Ну, очевидно, вы недостаточно знаете тонкости вычислений с плавающей запятой.

Смотри, например, http://download.oracle.com/docs/cd/E19957-01/806-3568/ncg_goldberg.html

Если вы делаете это на 32-битной Ubuntu, проблема, вероятно, заключается в том, что maxtime передается в память и, таким образом, теряет биты.

Одним из исправлений является изменение условного на


if (fabs(jp[0].t1 + jp[0].t2 + jp[0].t3 - maxtime) &lt DBL_EPSILON) {
 ...
}

1 голос
/ 17 июня 2011

В процессоре регистры с плавающей запятой имеют ширину 80 бит (10 байт).В памяти double имеет ширину 64 бита (8 байт).

Возможно, что в if сумма вычисляется и остается в регистрах ЦП, тогда как maxTime - эточитать из памяти, и таким образом был усечен.Могу объяснить странное поведение.

...