Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 42, средняя оценка - 4.76
kuzya
0 / 0 / 0
Регистрация: 10.06.2009
Сообщений: 4
#1

Проверка переполнения double - C++

10.06.2009, 18:39. Просмотров 5352. Ответов 16
Метки нет (Все метки)

Добрый день!

Подскажите пожалуйста, где можно почитать теорию.
Нужно решить задачу, написать функции на С++, которые бы проверяли
переполнение при сложении и умножении 2х double, а также проверка на переполнение (underflow) при вычитании/делении.

Если кто бросит ссылки на теорию - буду очень благодарен. Если кто поможет совет, тоже буду очень благодарен. Важно, чтоб я сам понял : ).

Предлагают double приводить к long double и сравнивать результат (long double) с максимальным значением для double.
Может, еще есть какие-то варианты решение, без приведения к более большему типу? Ведь нужно будет значение сравнивать с константой...
(хотя double на всех машинах поддерживающих IEEE числа с плавающей точкой равен 8 байтам...)

Вообщем, подскажите решения, кто как подобные проблемы решает.
Использую g++, linux. Хочеться, чтобы решение было на С++, желательно средствами языка, а не библиотек. Ну и конечно же, чтобы оно было кроссплатформенным...

(Хотя может оказаться так, что буду реализовывать через <limits> и long double)

Заранее спасибо)

Добавлено через 1 час 9 минут 45 секунд
Ура!
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.06.2009, 18:39     Проверка переполнения double
Посмотрите здесь:

Проверка арифметического переполнения для int - C++
Есть задача (из книги Лафоре ООП в С++, задача 4, глава 8): Создайте класс Int, основанный на упражнении 1 из главы 6 . Перегрузите...

Проверка double на переполнение - C++
Подскажите, пожалуйста, как проверить double на переполнение? Был такой вариант, но работает некорректно: template &lt;class Type&gt; ...

Проверка double на NaN и Infinity - C++
Как лучше проверить дабл на нотенамбер или бесконечность?

Проверка числа типа double на чётность/нечётность - C++
В программе необходимо проверить число типа double на то, является оно четным или нет. Это возможно как-то сделать или нет? Обычный метод,...

Защита от переполнения - C++
Ребят помоги создать защиту от переполнения через функцию scanf_s и убрать нолики в конечном ответе, вот код: #include &lt;stdio.h&gt; ...

Флаг переполнения - C++
Доброго времени суток! Подскажите, как проверить какую-либо определенную переменную типа double на переполнение (значениe -1.#IND00,...

СИ++ и контроль переполнения - C++
Можно ли как-нибудь в VS включить контроль переполнения при математических вычислениях? Чтоб, например, возникало исключение. Или это можно...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
kuzya
0 / 0 / 0
Регистрация: 10.06.2009
Сообщений: 4
10.06.2009, 18:44  [ТС]     Проверка переполнения double #2
Ура! Тему можно удалять!!! : )

Я вспомнил про <limits> и numeric_limits<double>m{in,ax}(), еще подсказали с long double, в итоге у меня все получилось. : )))

Прикрепил решение. Похваться и вдруг кому-то пригодиться : )
Зы: если у кого есть замечания по поводу решения - очень рад буду услышать их и то, как можно его улучшить. И конечно же, если кто-то поделиться другими способами решения этой (уже решенной) задачи, буду очень благодарен!

Кузя.
Вложения
Тип файла: txt solution.txt (1.4 Кб, 359 просмотров)
Evg
Эксперт CАвтор FAQ
17469 / 5707 / 362
Регистрация: 30.03.2009
Сообщений: 15,663
Записей в блоге: 26
10.06.2009, 19:42     Проверка переполнения double #3
Вообще для честного решения надо всё-таки читать стандарт IEEE-754 и смотреть, что должно быть. Та может быть NaN или сигнал FPFE.

Максимальное значение в double имеет порядок 10^308, в long double - 10^4932
Т.е. при умножении двух числе в районе максимального double'а ты получишь переполнение в long double (и соотвественно хрен знает какой результат). Т.е. твоё решение по сути является неправильным
Delphin_KKC
UNIX-way
709 / 494 / 17
Регистрация: 15.01.2009
Сообщений: 1,721
10.06.2009, 19:47     Проверка переполнения double #4
Цитата Сообщение от Evg Посмотреть сообщение
...Максимальное значение в double имеет порядок 10^308, в long double - 10^4932
Т.е. при умножении двух числе в районе максимального double'а ты получишь переполнение в long double...
С чего бы это? 10^308*10^308=10^616
Убедиться в правильности утверждения можно на примере:
10^3*10^3=10^6 <==> 1000*1000=1000000
Evg
Эксперт CАвтор FAQ
17469 / 5707 / 362
Регистрация: 30.03.2009
Сообщений: 15,663
Записей в блоге: 26
10.06.2009, 19:54     Проверка переполнения double #5
Посмотри файл /usr/include/fenv.h
Вот для этих делов там процедуры нахерачены. Надо через них работать. Код будет переносим на другие процессоры (по крайней мере на linux'е)

Добавлено через 39 секунд
Цитата Сообщение от Delphin_KKC Посмотреть сообщение
С чего бы это? 10^308*10^308=10^616
Убедиться в правильности утверждения можно на примере:
10^3*10^3=10^6 <==> 1000*1000=1000000
Блин точно. А я что-то грешным делом подумал, что там степени перемножать надо

Добавлено через 5 минут 12 секунд
В любом случае это более честный способ (учитывая то, что не на всех платформах есть long double):

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
#include <stdio.h>
#include "fenv.h"
 
void
mult (double d1, double d2)
{
  double res;
  int flags;
 
  printf ("=====\n");
 
  res = d1 * d2;
  flags = fetestexcept (FE_OVERFLOW);
 
  printf ("res=%e\n", res);
  printf ("flags=%d\n", flags);
 
  if (flags)
    printf ("overflow\n");
  else
    printf ("no overflow\n");
}
 
int
main (void)
{
  mult (1.0e100, 1.0e100);
  mult (1.0e200, 1.0e200);
}
Код
$ gcc a.c -lm
$ ./a.out 
=====
res=1.000000e+200
flags=0
no overflow
=====
res=inf
flags=8
overflow
kuzya
0 / 0 / 0
Регистрация: 10.06.2009
Сообщений: 4
10.06.2009, 21:06  [ТС]     Проверка переполнения double #6
2Evg: обязательно завтра копну fenv.h!

По поводу long double... Тоесть, если в стандарте C или C++ он есть, то в реализации этих стандартов на определенных архитектурах их может и не быть?

Я удовлетворился своим решением, это упражнение из книги по С++ Страуструпа. : ). Да и на видну его натянуть можно... Тут получаеться
кроссплатформенным, но только к linux привязано...
Про fenv.h я даже и не знал... теперь буду знать, спасибо большое! Раз через это можно еще и флаги состояния FPU смотреть.

Зы: (в коде) а там это, разве не #include <fenv.h> надо, вместо кавычек, и int из main"а вернуть? Если Вы скажите, что gcc не ругнулся, то я очень сильно удивлюсь... В любом случае код тоже завтра опробую.

Ребят, обоим большое спасибо!
Evg
Эксперт CАвтор FAQ
17469 / 5707 / 362
Регистрация: 30.03.2009
Сообщений: 15,663
Записей в блоге: 26
10.06.2009, 21:28     Проверка переполнения double #7
Цитата Сообщение от kuzya Посмотреть сообщение
По поводу long double... Тоесть, если в стандарте C или C++ он есть, то в реализации этих стандартов на определенных архитектурах их может и не быть?
Скажем так, в стандарте не сказано, какого размера должен быть long double. На некоторых архитектурах long double реализуется как эквивалент double'а.

Цитата Сообщение от kuzya Посмотреть сообщение
Я удовлетворился своим решением, это упражнение из книги по С++ Страуструпа. : ). Да и на видну его натянуть можно... Тут получаеться
кроссплатформенным, но только к linux привязано...
Про fenv.h я даже и не знал... теперь буду знать, спасибо большое! Раз через это можно еще и флаги состояния FPU смотреть.
Если не забуду - завтра на solaris'е проверю. Этот интерфейс специально разработан как кросс-платформенный, чтобы не ковыряться непосредственно в регистрах состояния. Так что возможно, что и на других юниксах он есть. И этот интерфейс базируется на требованиях стандарта IEEE-754. Вернее группа интерфесов, т.к. там есть ещё работа с округлениями и ещё чем-то.

Твой вариант скорее всего не будет правильно работать со всякими NaN'ами, INF'ами и прочей ерундой. Я не специалист в этой области, а потому какой-то пример подогнать затрудняюсь. Опять-таки если не забуду, тряхану специалистов. Есть ли какой-то "стандартный" способ для этих деяний - хз.

Кстати, у тебя 0 помножить на число вроде бы как неправильно отработает Добавить надобно

Цитата Сообщение от kuzya Посмотреть сообщение
Зы: (в коде) а там это, разве не #include <fenv.h> надо, вместо кавычек, и int из main"а вернуть? Если Вы скажите, что gcc не ругнулся, то я очень сильно удивлюсь...
Про кавычки - пальцы заплелись, правда хз почему gcc не ргунулся.
"return 0" просто забыл, но в этом случае компилятор обычно выдаёт warning, а не ошибку
Delphin_KKC
UNIX-way
709 / 494 / 17
Регистрация: 15.01.2009
Сообщений: 1,721
11.06.2009, 09:04     Проверка переполнения double #8
Цитата Сообщение от Evg Посмотреть сообщение
...Про кавычки - пальцы заплелись, правда хз почему gcc не ргунулся...
Невелика беда. Если инклуд в кавычках - то вначале ищется в папке с проектом (где, само собой, в нашем случае не обнаруживается), а потом - в папке инклудов компилятора. Если ж в угловых скобочках - то порядок поиска обратный.
Evg
Эксперт CАвтор FAQ
17469 / 5707 / 362
Регистрация: 30.03.2009
Сообщений: 15,663
Записей в блоге: 26
11.06.2009, 10:11     Проверка переполнения double #9
> Если не забуду - завтра на solaris'е проверю

Однако на solaris'е нету. Так что по сути дела это линуксовая фича (а точнее -glibc'шная)
Delphin_KKC
UNIX-way
709 / 494 / 17
Регистрация: 15.01.2009
Сообщений: 1,721
11.06.2009, 16:27     Проверка переполнения double #10
Цитата Сообщение от Evg Посмотреть сообщение
...Так что по сути дела это линуксовая фича (а точнее -glibc'шная)
Вот этот код:
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
#include <stdio.h>
#include "fenv.h"
//добавлено
#include <cstdlib>
void mult (double d1, double d2)
{
  double res;
  int flags;
 
  printf ("=====\n");
 
  res = d1 * d2;
  flags = fetestexcept (FE_OVERFLOW);
 
  printf ("res=%e\n", res);
  printf ("flags=%d\n", flags);
 
  if (flags)
    printf ("overflow\n");
  else
    printf ("no overflow\n");
}
 
int main (void)
{
  mult (1.0e100, 1.0e100);
  mult (1.0e200, 1.0e200);
  system("PAUSE");//добавлено
}
На Вин32 платформе компилятором DevCPP 4.9.9.2 собирается без ошибок. Строки с коментариями "//добавлено" добавлены для того, чтоб можно было использовать вызов систем. Скрин работы вот:
Миниатюры
Проверка переполнения double  
Evg
Эксперт CАвтор FAQ
17469 / 5707 / 362
Регистрация: 30.03.2009
Сообщений: 15,663
Записей в блоге: 26
11.06.2009, 16:38     Проверка переполнения double #11
Цитата Сообщение от Delphin_KKC Посмотреть сообщение
На Вин32 платформе компилятором DevCPP 4.9.9.2 собирается без ошибок.
А что такое DEVCpp. Это кака-ято среда разработки вод винду, базирующаяся на gcc+glibc?
kuzya
0 / 0 / 0
Регистрация: 10.06.2009
Сообщений: 4
11.06.2009, 16:40  [ТС]     Проверка переполнения double #12
2Evg: касательно return'а из main(): gcc таки выдает варнинг, но только если ему скормить -Wall!!! : ( Я удивлен и опечален. Да, и про 0 на число множить/делить... действительно протупил! Спасибо большое!, уже исправил код.
А про реализацию long double как double тоже что-то... протупил

2Delphin_KKC: я нигде в литературе не встречал того, чтобы "include.h" искали после текущего каталога в системном и не встречал, чтоб <include.h> искалось после систеного в текущем каталоге... если можно, скажите где я могу про это прочитать, пожалуйста.

Что касаеться fenv.h, то в нем, в начале, написано:
This file is part of the GNU C Library. Поэтому, даже незнаю что говорить про кросплатформенность/мультиосьность...
Хотя Delphin_KKC показал нам, что в винде работает. Даже незнаю, что и думать.
Evg
Эксперт CАвтор FAQ
17469 / 5707 / 362
Регистрация: 30.03.2009
Сообщений: 15,663
Записей в блоге: 26
11.06.2009, 16:46     Проверка переполнения double #13
Свои программы я как правило компиляю с -Wall -Werror
Меньше потом гемора и чище код
Delphin_KKC
UNIX-way
709 / 494 / 17
Регистрация: 15.01.2009
Сообщений: 1,721
11.06.2009, 16:48     Проверка переполнения double #14
Цитата Сообщение от Evg Посмотреть сообщение
А что такое DEVCpp. Это кака-ято среда разработки вод винду, базирующаяся на gcc+glibc?
Интегрированная среда на основе MinGW
http://www.bloodshed.net/devcpp.html
Evg
Эксперт CАвтор FAQ
17469 / 5707 / 362
Регистрация: 30.03.2009
Сообщений: 15,663
Записей в блоге: 26
11.06.2009, 16:53     Проверка переполнения double #15
Цитата Сообщение от Delphin_KKC Посмотреть сообщение
Интегрированная среда на основе MinGW
http://www.bloodshed.net/devcpp.html
Ну т.е. у тебя там стоИт glibc. Т.е. в этом отношении библиотечная поддержка совпадает с линуксовой
Delphin_KKC
UNIX-way
709 / 494 / 17
Регистрация: 15.01.2009
Сообщений: 1,721
11.06.2009, 18:22     Проверка переполнения double #16
Цитата Сообщение от kuzya Посмотреть сообщение
2Delphin_KKC: я нигде в литературе не встречал того, чтобы "include.h" искали после текущего каталога в системном и не встречал, чтоб <include.h> искалось после систеного в текущем каталоге... если можно, скажите где я могу про это прочитать, пожалуйста.
Честно говоря, не вспомню уже. Вот что пишут про инклуд у нас: http://www.cyberguru.ru/programming/...de-page64.html
У Кернигана и Ритчи написано что "зависит от реализации".
Только что проверял на DevCPP
Это оригинальный код:
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
#include <stdio.h>
#include "fenv.h"
#include <cstdlib>
 
void
mult (double d1, double d2)
{
  double res;
  int flags; 
 
  printf ("=====\n");
 
  res = d1 * d2;
  flags = fetestexcept (FE_OVERFLOW);
 
  printf ("res=%e\n", res);
  printf ("flags=%d\n", flags); 
 
  if (flags)
    printf ("overflow\n");
  else
    printf ("no overflow\n");
}
 
int main (void)
{
  mult (1.0e100, 1.0e100);
  mult (1.0e200, 1.0e200);
  system("PAUSE");
 
}
Всё компилируется.
А теперь я закинул в папку с проэктом пустой файлик с именем "fenv.h".
Код компилироваться отказался и выскочило куча ошибок по поводу что функция не определена.
После того, как я заменил "#include "fenv.h" " на это:
C++
1
#include <fenv.h>
Всё снова начало без ошибок компилиться (тот "подставной хедер" не удалял).
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.06.2009, 19:46     Проверка переполнения double
Еще ссылки по теме:

Переполнения безопастны? - C++
Насколько безопасна строчка: for(unsigned int b(UINT_MAX); ++b != UINT_MAX;) или такое нужно писать только так: unsigned int b(0);...

Ошибка переполнения буфера - C++
При первом запуске програма работает, после второго появляеться ошибка переполнения буфера. В чем дело?#include &lt;iostream&gt; #include...

Как отловить переполнения? - C++
Есть проект dll, в в нём экспортируемая функция, возвращающая BOOL, требуется при переполнении любой вещественной операции в теле этой...

Ошибка переполнения массива - C++
Здравствуйте. Задача легкая,нужно создать массив из 1000000 элементов,и найти 1000001,и вывести сообщение что не найден такой элемент. Но...

Избавиться от переполнения буфера (asm) - C++
Всем привет, на вашем форуме первый раз) Имея базовые знания по C++ и Assembler решил сварганить такую штуку: // test.cpp: определяет...


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

Или воспользуйтесь поиском по форуму:
Evg
Эксперт CАвтор FAQ
17469 / 5707 / 362
Регистрация: 30.03.2009
Сообщений: 15,663
Записей в блоге: 26
11.06.2009, 19:46     Проверка переполнения double #17
Что касается gcc, то по умолчанию для кавычек и угловых скобок он ищет по одним и тем же путям:

Код
$ gcc a.c -v
...
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include           <---- надпись выше означает, что оба поиска ведутся отсюда
 /usr/lib/gcc/i486-linux-gnu/4.2.4/include
 /usr/include
...
При этом есть опция -I-, означающая, что всё, что стоИт ДО этой опции, относится только к поиску по кавычкам

Код
$ mkdir qqq
$ mkdir rrr
$ gcc a.c -Iqqq -I- -Irrr -v
...
#include "..." search starts here:
 qqq      <------- с этого места начинается поиск по кавычкам
#include <...> search starts here:
 rrr      <------- с этого места начинается поиск по угловым скобкам
 /usr/local/include
 /usr/lib/gcc/i486-linux-gnu/4.2.4/include
 /usr/include
...
Добавлено через 1 минуту 14 секунд
Ну и ещё одно отличие gcc между кавычками и скобками - скобки считаются системными каталогами, а потому по файлам, подключенным через скобки подавляются warning'и
Yandex
Объявления
11.06.2009, 19:46     Проверка переполнения double
Ответ Создать тему
Опции темы

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