Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 08.07.2015, 14:53   #1
semenaa
Новичок
Джуниор
 
Регистрация: 08.07.2015
Сообщений: 5
По умолчанию errno и math_errhandling в С

набросал для лабы код. Вот он:
Код:
#include "math.h"
#include "stdio.h"
#include "errno.h"
#include "string.h"
#include "fenv.h"
#pragma STDC FENV_ACCESS ON
double member(unsigned long i)
{
   double z=(double)i;
   double a=1.0/log(z)/(z-1.0)/(z-1.0);
   return a;
}


int main()
{
   double a,sum=0.0;
   unsigned long  i;
   for (i=1;i<4294967295;i++)
   {    
      errno=0; //before the unpredictable calculation
      if (errno!=0)
      {         
         printf("%s\n", strerror(errno));
         return 1;      
      }         
      a=member(i);
      printf("i: %li  ", i);
      printf("a: %12.8e\n", a);
      errno=0; //before the unpredictable calculation
      sum+=a;   
      break;    
      if (errno==ERANGE)
      {         
         printf("The sum has reached infinite value. This is not converging series\n");
         return 1;      
      }         
      if (fabs(a)<=0.0001)//precision test 
         break;         
   }    
   printf("The sum is: %8e\n",sum);
   return 0;
}
Программа для вычисления суммы ряда с заданной точностью. Данные задачи уже в коде, члены ряда обозначены переменной а. Первое слагаемое стремится к бесконечности, стало быть, по определению, ряд расходится. Надо это показать и в программе. Хочу обыграть через errno последней операции.
Проблема в том, что не записывается при выполнении в errno никакой ошибки, а вывод первого слагаемого и суммы явно показывает inf. Вроде все как в референсах делал.

Последний раз редактировалось Stilet; 08.07.2015 в 15:05.
semenaa вне форума Ответить с цитированием
Старый 08.07.2015, 15:13   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
не записывается при выполнении в errno никакой ошибки
Не правда. Все записывается.
Код:
...
      a=member(i);
	  printf("Error is: %d",errno);
...
Сам все и увидишь.

А вот зачем ты break поставил я теряюсь в догадках.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 08.07.2015, 16:39   #3
semenaa
Новичок
Джуниор
 
Регистрация: 08.07.2015
Сообщений: 5
По умолчанию

ой, да тут просто нагромождение разного кода, пробовал и так, и эдак... break втыкал потому, что return из условия не срабатывал, а я хотел убедиться, что переполнение наличествует. Как вы посоветовали, тоже не выходит. Не отображается вообще ничего. То есть у меня вывод
Цитата:
i: 1 a: inf
The sum is: inf
и все на этом. Нету никаких упоминаний об errno. Компилятор GCC, может, опцию какую надо еще приписать?
semenaa вне форума Ответить с цитированием
Старый 09.07.2015, 00:28   #4
Krasiosoft
Форумчанин
 
Аватар для Krasiosoft
 
Регистрация: 01.06.2015
Сообщений: 497
По умолчанию

Переменная "а" уже на первом шаге inf, скорее всего проблема в самой формуле:
Код:
double a=1.0/log(z)/(z-1.0)/(z-1.0);
Если подставить другую формулу, все отлично работает.

На первом шаге у Вас выходит деление на 0, оно и дает в результате inf. Уверены, что так и должно быть?
Если помог, буду очень благодарен за Ваш отзыв (весы в левой нижней части сообщения).
Krasiosoft вне форума Ответить с цитированием
Старый 09.07.2015, 12:43   #5
semenaa
Новичок
Джуниор
 
Регистрация: 08.07.2015
Сообщений: 5
По умолчанию

Цитата:
Сообщение от Krasiosoft Посмотреть сообщение
Переменная "а" уже на первом шаге inf, скорее всего проблема в самой формуле:
Код:
double a=1.0/log(z)/(z-1.0)/(z-1.0);
Если подставить другую формулу, все отлично работает.

На первом шаге у Вас выходит деление на 0, оно и дает в результате inf. Уверены, что так и должно быть?
Вы, возможно, неправильно поняли. В задаче намеренно указана формула, приводящая к результатам в виде переполненного типа double. Для меня проблемой является то, что я вижу в выводе программы, что переменнst переполнены: a=inf, sum=inf, но при этом errno не принимает значение ERANGE, то есть не указывает на это. А я хочу, чтобы указывал. Но вот остается нулевым, и все тут. Есть гипотеза, что так происходит из-за того что последний выполняемый оператор в той строке - присваивание, проходящее успешно. Тогда возникает естественный вопрос: как это тогда обыграть, чтобы ошибка корректно обрабатывалась.
semenaa вне форума Ответить с цитированием
Старый 09.07.2015, 12:55   #6
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Код:
   bool ok=true;

   for (i=1;i<4294967295;i++)
   {    
      errno=0; //before the unpredictable calculation
      if (errno!=0)
      {         
         printf("%s\n", strerror(errno));
         return 1;      
      }         
      a=member(i);
	  ok=errno==ERANGE;
      printf("i: %li  ", i);
      printf("a: %12.8e\n", a);
      errno=0; //before the unpredictable calculation
	   sum+=a; 
      if (!ok)
      {         
         printf("The sum has reached infinite value. This is not converging series\n"); getchar();
         return 1;      
      }    

      

      if (fabs(a)<=0.0001)//precision test 
         break;         
   }
Идея ясна?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 09.07.2015, 13:40   #7
semenaa
Новичок
Джуниор
 
Регистрация: 08.07.2015
Сообщений: 5
По умолчанию

Да, получается. Попробовал щас fetestexcept из стандарта c99 - тоже получается. Не понял, в чем раньше прикол был, какой-то нюанс я не уловил, видимо. Прошу прощения за тупняк, за ваше потраченное на меня лоботряса время) ) ).
semenaa вне форума Ответить с цитированием
Старый 09.07.2015, 13:42   #8
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Не понял, в чем раньше прикол был
Ты же выше сказал: так происходит из-за того что последний выполняемый оператор в той строке - присваивание, проходящее успешно.
Что вполне закономерно. Так же действуют и другие ловцы ошибок, а не только errno. И так везде.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 09.07.2015, 14:03   #9
semenaa
Новичок
Джуниор
 
Регистрация: 08.07.2015
Сообщений: 5
По умолчанию

да, я убрал эту переменную а вообще и заменил функцией, а также убрал лишнее присваивание в функции (сразу в return формулу засунул) то есть случай
Цитата:
sum+=member (i)
таки записывает ошибку ERANGE, хотя там, по идее, тоже присвоение после сложения должно бысть. Магия, в общем, пока мне непонятная.
semenaa вне форума Ответить с цитированием
Старый 09.07.2015, 15:11   #10
Krasiosoft
Форумчанин
 
Аватар для Krasiosoft
 
Регистрация: 01.06.2015
Сообщений: 497
По умолчанию

Цитата:
Сообщение от semenaa Посмотреть сообщение
В задаче намеренно указана формула, приводящая к результатам в виде переполненного типа double.
Тогда как можно посчитать сумму ряда с заданной точностью? Ведь на 1-ом шагу сумма будет inf, а далее уже, что не прибавляй/отнимай от бесконечности, то бесконечность и будет.
Если помог, буду очень благодарен за Ваш отзыв (весы в левой нижней части сообщения).
Krasiosoft вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Firebird: INET/inet_error: read errno = 104 JTG Операционные системы общие вопросы 1 22.07.2009 16:26