Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.93/55: Рейтинг темы: голосов - 55, средняя оценка - 4.93
-7 / 21 / 7
Регистрация: 16.12.2016
Сообщений: 708
1

Что такое точность epsilon?

18.02.2018, 23:14. Просмотров 10552. Ответов 29
Метки нет (Все метки)

Напишите программу, которая оценивает значение математической константы e по формуле e*=*1*+*1/1!*+*1/2!*+*1/3!*+*... с заданной введенной точностью epsilon.

ну вот написал я прогу, Е у меня высчитывается, а что за ЭПСИЛОН? какона работает как ее задать? зачем она ваще нужна и где могла бы пригодиться?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
18.02.2018, 23:14
Ответы с готовыми решениями:

Что такое файловый буфер? Что такое режим (модификатор) доступа, при работе с файлами?
Что такое файловый буфер? Что такое режим (модификатор) доступа, при работе с файлами?

Что такое IIS и что такое PWS? Почему одно без другого не работает?
вот уже второй день пытаюсь немного разобраться в АСП. накидал небольшую тестовую страничку. но с...

Что такое рекурсивный тип данных? Что такое конструкция рекурсивного типа?
Что такое рекурсивный тип данных? Что такое конструкция рекурсивного типа?

Что такое напряжение и что такое сила тока с позиции заряженных частиц
Объясните пожалуйста, что такое напряжение и что такое сила тока с позиции заряженных частиц....

29
Эксперт C
24935 / 15436 / 3269
Регистрация: 24.12.2010
Сообщений: 33,285
19.02.2018, 00:23 2
Цитата Сообщение от SadiQ228 Посмотреть сообщение
ну вот написал я прогу
Ну и что? Я тоже прогу написал.
Цитата Сообщение от SadiQ228 Посмотреть сообщение
а что за ЭПСИЛОН?
Это вы должны сказать. Я не в курсах. Вашей проги не видел.
Цитата Сообщение от SadiQ228 Посмотреть сообщение
зачем она ваще нужна и где могла бы пригодиться?
Я тоже в полной растерянности.
Задачу-то я понимаю, она более-менее стандартна. А вот вопросов ваших мне не понять, увы!
1
1158 / 705 / 480
Регистрация: 25.04.2016
Сообщений: 1,984
19.02.2018, 01:01 3
пошарил значит на википедии, и вот что там нашел:

Эпсилон в программировании - точность численного типа данных (наименьшее положительное значение eps, для которого будет соблюдаться неравенство 1 + eps > 1).

Упоминания о чем-то схожем попадаются в книжке Подбельского В. В. "Введение в программирование на языке си" 2004 года, которую можно откопать, например тут, в ней, на странице 83 приведен алгоритм "оценки машинного нуля", и сдается мне, что этот мышиный ноль именно то, что вам нужно. Если описать эту зверушку в коде, получится примерно так:

C
1
2
3
4
5
6
7
// машинный эпсилон для сравнения вещественных
double m_eps (void)
{
    double e = 1.0;
    while (1.0 + e / 2.0 > 1.0) e /= 2.0;
    return e;
}
Это то, что удалось нарыть на скорую руку, но если честно, совершенно не представляю, что за фигню тут написал...
2
1462 / 1170 / 551
Регистрация: 08.01.2012
Сообщений: 4,510
19.02.2018, 05:13 4
Цитата Сообщение от SadiQ228 Посмотреть сообщение
введенной точностью epsilon
т.е сами задаете
C
1
2
3
4
5
6
    double a,e;
    double eps=1e-15;//оно
    int n;
    for(e=a=n=1; a>=eps; n++,a/=n)
        e+=a;
    printf("%lf\n",e);
2
-7 / 21 / 7
Регистрация: 16.12.2016
Сообщений: 708
20.02.2018, 01:14  [ТС] 5
ну вот мое задание:
Напишите программу, которая вычисляет значение e^x по формуле e^x*=*1*+*x/1!*+*x^2/2!*+*x^3/3!*+*...для введенных x и точности epsilon.
Вот мой код:
Кликните здесь для просмотра всего текста
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include "stdafx.h"
#include <math.h>
#include <stdio.h>
double e(double epsilon, int x);
long int f(int n);
int main()
{
    double epsilon;
    int x;
    long int n;
    printf("Enter EPSILON: ");
    scanf_s("%lf", &epsilon);
    printf("Enter X: ");
    scanf_s("%d", &x);
    printf("%lf", e(epsilon, x));
    return 0;
}
double e(double epsilon, int x)
{
    double rezult = 0.0;
    double add = 1.0;
    int i = 0;
    do
    {
        i++;
        rezult = add + (pow(x, i) / f(i));
    } while ((pow(2.718, x)-rezult) > epsilon);
    return rezult;
}
 
long int f(int n)
{
    return (n < 2) ? 1 : n * f(n - 1);
}


результат вывода странный, что я делаю не так?

Добавлено через 17 минут
например при EPSILON = 0.5 а X = 2 выдает INF в выводе

Добавлено через 36 минут
Только что заменил глупую ошибку в функции подсчета, вроде заработало, но прошу экспертной оценки
C
1
2
3
4
5
6
7
8
9
10
11
double e(double epsilon, int x)
{
    double rezult = 1.0;
    int i = 0;
    do
    {
        i++;
        rezult += (pow(x, i) / f(i));
    } while ((pow(2.718, x)-rezult) > epsilon);
    return rezult;
}
0
2701 / 1649 / 346
Регистрация: 09.09.2017
Сообщений: 6,756
20.02.2018, 10:13 6
Считается что вы не знаете желаемого значения, иначе зачем его вычислять. То есть нужно чтобы очередной член последовательности был меньше epsilon. То есть a[i] < epsilon
Вместо ресурсоемких pow() и f() (это факториал, наверное?) используйте предыдущий член:
a[i] = x(i) / i!
a[i+1] = x(i+1) / (i+1)! = a[i]*x/i
Похоже, вы пытаетесь разобраться самостоятельно, поэтому приводить в виде кода не стану.
1
-7 / 21 / 7
Регистрация: 16.12.2016
Сообщений: 708
20.02.2018, 19:14  [ТС] 7
ну а так то верно же считает?
0
Модератор
Эксперт Python
27031 / 14192 / 2742
Регистрация: 12.02.2012
Сообщений: 23,283
Записей в блоге: 3
21.02.2018, 07:29 8
Цитата Сообщение от SadiQ228 Посмотреть сообщение
но прошу экспертной оценки
- очень плохой код. Прежде, чем программировать, нужно вывести рекуррентную формулу, которая связывает следующий член ряда с предыдущим:

https://www.cyberforum.ru/cgi-bin/latex.cgi?{a}_{n}={x}^{n}/n! https://www.cyberforum.ru/cgi-bin/latex.cgi?{a}_{n+1}={x}^{n+1}/(n+1)! отсюда https://www.cyberforum.ru/cgi-bin/latex.cgi?{a}_{n+1}/{a}_{n}=x/(n+1)

Теперь пишем код:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <stdlib.h>
 
double myExp(double x, double eps)
{
       double n=0,s=1,a=1;
       while(a>eps)
       {
          a=a*x/(n+1);
          s+=a;
          n++;
       }
       return s;
}                  
 
int main(int argc, char *argv[])
{
 
  printf("%lf %lf\n",myExp(1.0, 1e-15), exp(1.0));  // для сравнения выведено значение стандартной экспоненты
  system("PAUSE");  
  return 0;
}
Да, про epsilon. В таких задачах это не машинное эпсилон (о чем писал stake-k26), а задаваемая точность - суммирование бесконечного ряда идет до тех пор, пока очередной член ряда не станет меньше этой задаваемой точности.
1
2701 / 1649 / 346
Регистрация: 09.09.2017
Сообщений: 6,756
21.02.2018, 10:44 9
Цитата Сообщение от SadiQ228 Посмотреть сообщение
ну а так то верно же считает?
Код
x       eps     exp             SadiQ228's exp  Catstail's exp
0.1     1e-20   1.105171        1.105171        1.105171
3.8     1e-20   44.701184       44.701184       44.701184
3.9     1e-20   49.402449       49.402448       49.402449
10      1e-20   22026.465795    21756.148596    22026.465795
Нормальный способ все же точнее
Кстати, ни тот ни другой способ толком не работают при отрицательном аргументе
1
1462 / 1170 / 551
Регистрация: 08.01.2012
Сообщений: 4,510
21.02.2018, 11:27 10
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    double xa,xb,dx,x;
    double eps=1e-15;
    double f,el;
    int i,ns,n;
    printf("xa xb dx:");
    scanf("%lf%lf%lf",&xa,&xb,&dx);
    ns=(int)((xb-xa)/dx)+1;
    for(x=xa,i=0; i<ns; i++, x+=dx)
    {
        f=0;
        for(el=n=1; el<-eps || el>eps; n++)
        {
            f+=el;
            el*=x/n;
        }
        printf("%9lf %15lf %15lf\n",x,f,exp(x));
    }
делов то
0
Модератор
Эксперт Python
27031 / 14192 / 2742
Регистрация: 12.02.2012
Сообщений: 23,283
Записей в блоге: 3
21.02.2018, 13:20 11
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Нормальный способ все же точнее
- нормальный - это библиотечный? Так мой код к нему весьма близок. А при отрицательном аргументе ряд станет знакочередующимся и действительно будет потеря точности. Избежать этой потери можно так:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
#include <stdlib.h>
 
double myExp(double x, double eps)
{
       double n=0,s=1,a=1;
       
       if (x < 0) 
          return (1.0/myExp(-x,eps));   
       else
       {
          while(a>eps)
          {
            a=a*x/(n+1);
            s+=a;
            n++;
          }
          return s;
       }   
}                  
 
int main(int argc, char *argv[])
{
  printf("%le %le\n",myExp(-10.0, 1e-15), exp(-10.0));  
  system("PAUSE");  
  return 0;
}
Кстати, совершенно бессмысленно задавать точность 1e-20. Поскольку тип double не вытянет более 15-16 значащих цифр.
0
2701 / 1649 / 346
Регистрация: 09.09.2017
Сообщений: 6,756
21.02.2018, 15:44 12
Цитата Сообщение от Catstail Посмотреть сообщение
- нормальный - это библиотечный?
Нормальный это ваш, с использованием предыдущего члена. Вряд ли библиотечная реализация сильно отличается, разве что там могут использовать таблицу.
Цитата Сообщение от Catstail Посмотреть сообщение
Избежать этой потери можно так:
А можно и так:
C
1
while(fabs(a)>eps)
Если что, мой пост был не с целью критики а анализ библиотечной реализации, вашей и SadiQ228'а. Как ни странно, по эффективности методы не так уж сильно отличались... ну за исключением того, что вычисление факториала и степени с нуля давало громадную ошибку. Но это я еще перепроверю

Добавлено через 1 час 16 минут
Итак, результаты
библиотечный exp(): 0.040448 мкс
функция SadiQ228'а: 1.07945 мкс
функция Catstail'а: 0.142243 мкс
То есть способ с использованием предыдущего значения в 7,5 раз быстрее "лобового", но в 3,5 раза медленнее библиотечного (наверняка там пошаманили с оптимизациями). Если поставить epsilon = 1e-5 то результаты ближе:
exp(): 0.040998
SadiQ228'а: 0.814409
Catstail'а: 0.0630968
1
Модератор
Эксперт Python
27031 / 14192 / 2742
Регистрация: 12.02.2012
Сообщений: 23,283
Записей в блоге: 3
21.02.2018, 16:19 13
Библиотечные функции вряд ли построены по итерационному принципу. Скорее всего - аппроксимация подходящим полиномом.
0
2701 / 1649 / 346
Регистрация: 09.09.2017
Сообщений: 6,756
21.02.2018, 16:40 14
Catstail, учитывая, что разница всего в 1.5 раза, возможно что и через ряд считалось
0
-7 / 21 / 7
Регистрация: 16.12.2016
Сообщений: 708
11.03.2018, 00:26  [ТС] 15
ребят, продолжая тему точности, пытаюсь высчитать E по другому ряду.
1/e = (-1)^n/n!; n=2

пытаюсь сделать но ответы удивляют, подскажите где ошибаюсь?
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
long double exp2(long double epsilon)
{
    int n = 2; //счетчик
    long double s = 0; //сумма ряда
    long double a = 0; //следующий член
        while (s>epsilon)
        {
            if (n % 2 == 0)
            {
                a = 1 / f(n);
                s += a;
                n++;
            }
            else
            {
                a = -1 / f(n);
                s += a;
                n++;
            }
        }
        return s;
}
интересует не только почему считает не верно, а так же как избавиться от функции факториала
0
Эксперт C
24935 / 15436 / 3269
Регистрация: 24.12.2010
Сообщений: 33,285
11.03.2018, 00:56 16
Лучший ответ Сообщение было отмечено SadiQ228 как решение

Решение

Цитата Сообщение от SadiQ228 Посмотреть сообщение
как избавиться от функции факториала
Легко. Просто надо вспомнить, что n! = n*(n-1)!

Добавлено через 8 минут
C
1
2
3
4
5
6
double s = 0, a = 1;
while (fabs(a) > eps) {
  s += a;
  a = (-1)*a/n;
  n++;
}
Типа того. А где ты здесь видишь факториалы? Хотя они, конечно, есть

Добавлено через 3 минуты
Цитата Сообщение от Байт Посмотреть сообщение
n! = n*(n-1)!
Эта формула в англоязычной литературе называется Factoral Killer В вольном переводе - Убивец факториалов
2
-7 / 21 / 7
Регистрация: 16.12.2016
Сообщений: 708
11.03.2018, 01:52  [ТС] 17
спасибо большое, однако осталось чуть не понято следующее:
n! = n*(n-1)! это же классическая рекурентная формула, однако конечное значение нам не известно, так откуда мы вычитаем единицу то на первой интерации цикла?)
0
2701 / 1649 / 346
Регистрация: 09.09.2017
Сообщений: 6,756
11.03.2018, 07:52 18
Счет в вашем ряду идет с 1, а факториал единицы вполне известен
0
Эксперт C
24935 / 15436 / 3269
Регистрация: 24.12.2010
Сообщений: 33,285
11.03.2018, 12:28 19
Лучший ответ Сообщение было отмечено SadiQ228 как решение

Решение

Цитата Сообщение от SadiQ228 Посмотреть сообщение
так откуда мы вычитаем единицу то на первой интерации цикла?)
Придется переписать формулу по-другому. Специально для вас
(n+1)! = (n+1)*n!
1
-7 / 21 / 7
Регистрация: 16.12.2016
Сообщений: 708
17.03.2018, 22:34  [ТС] 20
прошу прощения но ваша формула так же считает как и у меня по какой то причине и ответ не приближен даже близко к 0.36787944117 как же так не понял? В любой комбинации переменных единица остается в целой части
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.03.2018, 22:34

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

Что такое монитор и что такое мьютекс? Это же разные вещи?
Здравствуйте. В разных айти-статьях по-разному используют эти термины, причём часто их путают друг...

Что такое токен? Что такое сессия? Отличия от куки
Что такое токен и сессии ? в чем отличия от куков ? Безопасно ли использовать куки? можно ли...

Что такое метод equals() и что такое класс Object
Ответи на два вопроса очень надо 1) Что такое метод equals(). Чем он отличается от операции ==....

Объект TDictionary. Что такое ключ и что такое значение?
Из прочитанного в гугле понял что это нечто наподобие какого-то словаря: Коллекция пар...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.