Оценка эпсилон машины в С
Я новичок в C и пытаюсь найти машинный epsilon (1.0 + macheps > 1.0), eta (eta > 0.0) и MAX (MAX РЕДАКТИРОВАТЬ: Исправлена ошибка формата. РЕДАКТИРОВАТЬ 2: Разве вышеприведенный код не должен повысить точность? Что мне не хватает? EDIT3: все еще не дает правильные мачепы для длинных дублей./* macheps eta max */
#include <stdio.h>
#include <math.h>
#include <float.h>
#define TYPE long double
int main(void)
{
TYPE macheps = (TYPE) 1.0;
TYPE eta = (TYPE) 1.0;
TYPE maksymilian = (TYPE) 2.0;
TYPE real_macheps;
TYPE real_eta;
TYPE real_maksymilian;
TYPE something = (TYPE) 1.0 + (TYPE) macheps;
while ((TYPE) something > (TYPE) 1.0)
{
real_macheps = (TYPE) macheps;
printf("%e ", (TYPE) real_macheps);
macheps = (TYPE) macheps/(TYPE) 2.0;
something = (TYPE) 1.0 + (TYPE) macheps;
}
printf("%e\n", (TYPE) real_macheps);
while ((TYPE) eta > (TYPE) 0.0)
{
real_eta = (TYPE) eta;
eta = (TYPE) eta/(TYPE) 2.0;
}
printf("%e\n", (TYPE) real_eta);
while ((TYPE) maksymilian != INFINITY)
{
(real_maksymilian) = (TYPE) maksymilian;
maksymilian = (TYPE) maksymilian*(TYPE) 2.0;
}
real_maksymilian = (TYPE) real_maksymilian * (TYPE) (2.0-(TYPE) real_macheps);
printf("%e\n", (TYPE) real_maksymilian);
}
3 ответа
Ваша программа будет вызывать неопределенное поведение. В С, long
средства long int
и не long double
,
long
это сокращение для long signed int
и, следовательно, целочисленный тип. использование long double
вместо.
В зависимости от того, как числа, которые не могут быть представлены, округляются, (1.0 + machepsfloat) > 1.0
всегда может быть правдой. Проверьте FLT_ROUNDS
от <float.h>
определить поведение округления вашей реализации.
Забыл опубликовать исправленный код. Я должен был обойти, но это работает:
/* macheps eta max */
#include <stdio.h>
#include <math.h>
#include <float.h>
#define TYPE long double /* printf 'e' for float and double, 'Le' for long double */
/* used_type: float 0, double 1, long double 2 */
int main(void)
{
int used_type = 2;
TYPE macheps = (TYPE) 1.0;
TYPE eta = (TYPE) 1.0;
TYPE maksymilian = (TYPE) 1.0;
TYPE real_macheps = 0.0;
TYPE real_eta = 0.0;
TYPE real_maksymilian = 0.0;
TYPE something = (TYPE) 1.0 + (TYPE) macheps;
while ((TYPE) something > (TYPE) 1.0)
{
real_macheps = (TYPE) macheps;
macheps = (TYPE) macheps/(TYPE) 2.0;
something = (TYPE) 1.0 + (TYPE) macheps;
}
while ((TYPE) eta > (TYPE) 0.0)
{
real_eta = (TYPE) eta;
eta = (TYPE) eta/(TYPE) 2.0;
}
while ((TYPE) maksymilian != INFINITY)
{
(real_maksymilian) = (TYPE) maksymilian;
maksymilian = (TYPE) maksymilian*(TYPE) 2.0;
}
real_maksymilian = (TYPE) real_maksymilian * (TYPE) (2.0-(TYPE) real_macheps);
if (used_type == 2)
{
printf("%Le\n", (TYPE) real_macheps);
printf("%Le\n", (TYPE) real_eta);
printf("%Le\n", (TYPE) real_maksymilian);
}
else
{
printf("%e\n", (TYPE) real_macheps);
printf("%e\n", (TYPE) real_eta);
printf("%e\n", (TYPE) real_maksymilian);
}
}