Контакт с проблемами точности в числах с плавающей запятой

Big o (1) называется постоянным временем, но каково точное время в мс

Большая O запись (и маленькая [ 113] o , также, кстати, не представляет какого-либо конкретного значения , оно представляет собой рост необходимых ресурсов в зависимости от размера входных данных. Он отвечает на вопрос: «если я выполню свой алгоритм для данных в два раза больше, это займет столько же времени или вдвое больше, либо будет экспоненциально хуже - больше или меньше?»

Одна наносекунда, миллиард лет и любое другое конкретное значение - все O (1).

Что касается вычислительных затрат на типичные операции с массивами, то все, что требует (возможно, в худшем случае) просмотра всего массива, будет по крайней мере O ( длина массива ). С функциональными методами, такими как reduce, map и т. Д., Сложность функций обратного вызова также имеет значение - обратный вызов может быть O (1), но также может быть O (длина массива ) или O ( длина некоторого другого массива ).

9
задан xan 26 February 2009 в 15:54
поделиться

8 ответов

Очень простой и эффективный путь к раунду число с плавающей точкой к целому числу:

int rounded = (int)(f + 0.5);

Примечание: это только работает если f всегда положительно. (спасибо j случайный хакер)

5
ответ дан 4 December 2019 в 05:58
поделиться

То, когда Вы используете арифметическое строгое равенство с плавающей точкой, почти бессмысленно. Вы обычно хотите соответствовать диапазону допустимых значений.

Обратите внимание, что некоторые значения не могут быть представлены точно как плавающая точка vlues.

Посмотрите то, Что Каждый Программист Должен Знать Об Арифметике С плавающей точкой и Сравнении чисел с плавающей точкой.

15
ответ дан 4 December 2019 в 05:58
поделиться

Если Вы не считали его, заголовок данной статьи действительно корректен. Рассмотрите чтение его, для получения дополнительной информации об основных принципах арифметики с плавающей точкой на современных компьютерах, некоторых ловушках и объяснениях относительно того, почему они ведут себя способ, которым они делают.

11
ответ дан 4 December 2019 в 05:58
поделиться

Нет никакой проблемы точности.

Результат, который Вы получили (1.9999999999999996), отличался от математического результата (2) полем 1E-16. Это довольно точно, рассматривая Ваш вход "4.600".

У Вас действительно есть округляющаяся проблема, конечно. Значение по умолчанию, округляющееся в C++, является усечением; Вы хотите что-то подобное решению Кипа. Детали зависят от Вашего точного домена, сделайте Вы ожидаете round(-x)== - round(x) ?

12
ответ дан 4 December 2019 в 05:58
поделиться

Если точность действительно важна затем, необходимо рассмотреть использование чисел двойной точности с плавающей точкой, а не просто плавающей точки. Хотя от Вашего вопроса действительно кажется, что Вы уже. Однако у Вас все еще есть проблема с проверкой определенные значения. Вам нужен код вроде (предположение, что Вы проверяете свое значение по нулю):

if (abs(value) < epsilon)
{
   // Do Stuff
}

где "эпсилон" - некоторые маленькие, но не нулевое значение.

5
ответ дан 4 December 2019 в 05:58
поделиться

Десятичные числа использования: decNumber ++

2
ответ дан 4 December 2019 в 05:58
поделиться

На компьютерах числа с плавающей точкой никогда не точны. Они - всегда просто близкое приближение. (1e-16 близко.)

Иногда существуют скрытые биты, которые Вы не видите. Иногда основные правила алгебры больше не применяются: a*b! = b*a. Иногда сравнение регистра к памяти разоблачает эти тонкие различия. Или использование математического сопроцессора по сравнению с библиотекой операций с плавающей точкой во время выполнения. (Я делал этот waayyy tooo долго.)

C99 определяет: (Посмотрите в math.h),

double round(double x);
float roundf(float x);
long double roundl(long double x);

.

Или можно прокрутить собственное:

template<class TYPE> inline int ROUND(const TYPE & x)
{ return int( (x > 0) ? (x + 0.5) : (x - 0.5) ); }

Для эквивалентности с плавающей точкой попробуйте:

template<class TYPE> inline TYPE ABS(const TYPE & t)
{ return t>=0 ? t : - t; }

template<class TYPE> inline bool FLOAT_EQUIVALENT(
    const TYPE & x, const TYPE & y, const TYPE & epsilon )
{ return ABS(x-y) < epsilon; }
3
ответ дан 4 December 2019 в 05:58
поделиться

Можно прочитать данную статью для нахождения то, что Вы ищете.

Можно получить абсолютное значение результата, как замечено здесь:

x = 0.2;  
y = 0.3;  
equal = (Math.abs(x - y) < 0.000001)  
2
ответ дан 4 December 2019 в 05:58
поделиться
Другие вопросы по тегам:

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