Дополнение с плавающей точкой: проблемы потери точности

Среда программирования Unix Kernighan и Щукой.

The Unix Programming Environment

[еще 114], чем какая-либо другая книга, это преподавало мне преимущества в создании маленьких, легко протестированных инструментов, которые могут быть объединены, чтобы сделать большие вещи.

9
задан Eamon Nerbonne 10 August 2009 в 08:20
поделиться

3 ответа

Есть еще один однопроходный алгоритм, который немного меняет порядок вычислений. В псевдокод:

n = 0
mean = 0
M2 = 0

for x in data:
    n = n + 1
    delta = x - mean
    mean = mean + delta/n
    M2 = M2 + delta*(x - mean)  # This expression uses the new value of mean

variance_n = M2/n         # Sample variance
variance = M2/(n - 1)     # Unbiased estimate of population variance

(Источник: http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance )

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

6
ответ дан 4 December 2019 в 14:30
поделиться

IEEE предоставляет четыре режима округления (в сторону -inf, в сторону + inf, в сторону 0, ближайший). Похоже, вы хотите, чтобы к + inf. В C90 или C ++ нет стандартного элемента управления. C99 добавил заголовок , который также присутствует как расширение в некоторых реализациях C90 и C ++. Чтобы соответствовать стандарту C99, вам нужно написать что-то вроде:

#include <fenv.h>
#pragma STDC FENV_ACCESS ON

int old_round_mode = fegetround();
int set_round_ok = fesetround(FE_UPWARD);
assert(set_round_ok == 0);
...
int set_round_ok = fesetround(old_round_mode);
assert(set_round_ok == 0);

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

6
ответ дан 4 December 2019 в 14:30
поделиться

Если вы не беспокоитесь о точности, а только об отрицательной дисперсии, почему бы вам просто не сделать V (x) = Max (0, E (X ^ 2) - E (X) ^ 2)

2
ответ дан 4 December 2019 в 14:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: