грех, потому что, коричневая и погрешность округления

Это действительно помогает. Я предложил бы брать пробную версию и выполнить ее через часть Вашей кодовой базы, которая Вы думаете, пропущен. Эти инструменты генерируют много ложных положительных сторон. Как только Вы пробрались через них, Вы, вероятно, найдете переполнение буфера или два, который может сохранить много горя в ближайшем будущем. Кроме того, попробуйте по крайней мере два/три варианта (и также часть материала OpenSource).

5
задан chux - Reinstate Monica 13 October 2017 в 10:34
поделиться

7 ответов

Двойник IEEE хранит 52 бита мантиссы с "неявным ведущим один », образующий 53-битное число. Ошибка в нижнем бите результата следовательно, составляет примерно 1/2 ^ 53 шкалы чисел. Ваш вывод того же порядка, что и 1.0, так что получается ровно один часть 10 ^ 16 (потому что 53 * log (2) / log (10) == 15.9).

Так что да. Это о пределе ожидаемой точности. я не уверен, какой метод ULP вы используете, но подозреваю, что вы применяет его неправильно.

13
ответ дан 18 December 2019 в 05:21
поделиться

Ответ: только 0 для греха (Пи) - Вы включили все цифры Пи?

-Кто-нибудь еще заметил явное отсутствие иронии / чувства юмора здесь ?

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

Есть два источника ошибок. Функция sin () и приближенное значение M_PI. Даже если бы функция sin () была «совершенной», она не вернула бы ноль, если бы значение M_PI также не было совершенным, а это не так.

1
ответ дан 18 December 2019 в 05:21
поделиться

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

#include <math.h>
#include <stdio.h>
#include <stdlib.h>

#define HALF 0.5
#define GREATER_EQUAL_HALF(X) (X) >= HALF

double const M_PI = 2 * acos(0.0);

double round(double val, unsigned  places = 1) 
{
    val = val * pow(10.0f, (float)places);
    long longval = (long)val;
    if ( GREATER_EQUAL_HALF(val - longval) ) {
       return ceil(val) / pow(10.0f, (float)places);
    } else {
      return floor(val) / pow(10.0f, (float)places);
    }
}

int main() 
{
    printf("\nValue %lf", round(sin(M_PI), 10));
    return 0;
}
0
ответ дан 18 December 2019 в 05:21
поделиться

Я думаю, что это будет зависеть от системы. Я не думаю, что в Стандарте есть что сказать о том, насколько точными будут трансцендентные функции. К сожалению, я не помню, чтобы я видел какое-либо обсуждение точности функций, поэтому вам, вероятно, придется выяснить это самостоятельно.

0
ответ дан 18 December 2019 в 05:21
поделиться

@Josh Kelley - ok serious answer.
В общем, вы никогда не должны сравнивать результаты любых операций с числами с плавающей запятой или двойными числами друг с другом.

Единственное исключение - назначение.
float a = 10.0;
float b = 10.0;
then a == b

В противном случае вам всегда придется писать некоторую функцию, например bool IsClose (float a, float b, float error), чтобы вы могли проверить, находятся ли два числа в пределах «ошибки» друг от друга.
Не забудьте также проверить знаки / использовать фабрики - вы можете иметь -1.224647e-16

6
ответ дан 18 December 2019 в 05:21
поделиться

Я получаю точно такой же результат в своей системе - я бы сказал, что он достаточно близок

Я бы решил проблему, изменив строку формата на "% f \ n" :)

Однако это дает вам "лучший" результат или, по крайней мере, в моей системе он дает -3.661369e-245

#include <stdio.h>
#include <math.h>

int main(int argc, char *argv[]) {
    printf("%e\n", (long double)sin(M_PI));
    return 0;
}
0
ответ дан 18 December 2019 в 05:21
поделиться
Другие вопросы по тегам:

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