Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > как сдетектировать переполнение?


Автор: mrgloom 23.5.2013, 16:20
Код

int dist= sqrt((double)(x_pr-n_x1)*(x_pr-n_x1)+(y_pr-n_y1)*(y_pr-n_y1));

в коде встречается такая строчка и dist получается отрицательным числом, я так предполагаю, что происходит переполнение из-за того что в sqrt слишком большое число?
как этого можно сдетектировать или избежать?

Автор: bsa 23.5.2013, 16:55
сначала результат присвоить переменной типа double, затем проверить на [0;INT_MAX] и уже после только присваивать целочисленной переменной.

Автор: mrgloom 23.5.2013, 17:16
Цитата

затем проверить на [0;INT_MAX] 

ну так dist будет отрицательным же(т.е. достаточно проверить на <0), т.к. будет больше INT_MAX(или при преобразовании в дабл что измениться?).
а если число 2 раза выйдет за пределы и снова станет положительным? (или такого не может быть?)

Автор: baldina 23.5.2013, 17:18
http://codepad.org/T9hEQaag

Автор: volatile 24.5.2013, 00:51
Цитата(mrgloom @  23.5.2013,  17:16 Найти цитируемый пост)
а если число 2 раза выйдет за пределы и снова станет положительным? (или такого не может быть?) 

Может быть что угодно. Если не ошибаюсь, приведение непомещающегося дабл к инт, это UB.

Цитата(baldina )

    if (d <= std::numeric_limits<int>::max()) {
      int dist = static_cast<int>(d);

точнее так
Код

    if (floor (d) <= std::numeric_limits<int>::max()) {
либо
    if (d < 1. + std::numeric_limits<int>::max()) {

ну и на нижнюю границу тоже, не помешает проверить.

а чтоб не изобретать велосипед, смотрите boost::numeric_cast<>

Автор: mrgloom 24.5.2013, 08:42
isfinite только в c++11 ? как же раньше без этого жили?

и я не понял метод проверить int на переполнение это положить его в double и проверить на выход за границы int? а для double есть своя функция isfinite ? почему её тогда и для int нету?

Автор: baldina 24.5.2013, 10:08
Цитата(mrgloom @  24.5.2013,  08:42 Найти цитируемый пост)
а для double есть своя функция isfinite ? почему её тогда и для int нету?

потому что в http://ru.wikipedia.org/wiki/%D0%A7%D0%B8%D1%81%D0%BB%D0%BE_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D0%B7%D0%B0%D0%BF%D1%8F%D1%82%D0%BE%D0%B9 есть такое специальное значение, а все числа int правильные (по значению невозможно определить, было ли переполнение). в С/С++ нет средств проверки переполнения целочисленных арифметических операций, хотя процессор имеет такие средства (http://ru.wikipedia.org/wiki/%D0%A0%D0%B5%D0%B3%D0%B8%D1%81%D1%82%D1%80_%D1%84%D0%BB%D0%B0%D0%B3%D0%BE%D0%B2).

Цитата(mrgloom @  24.5.2013,  08:42 Найти цитируемый пост)
isfinite только в c++11 ? как же раньше без этого жили?

можно выполнить проверку x==x, если x - NaN, должно быть false
фанаты могут опереться на стандарт и проверять http://ru.wikipedia.org/wiki/%D0%A7%D0%B8%D1%81%D0%BB%D0%BE_%D0%B4%D0%B2%D0%BE%D0%B9%D0%BD%D0%BE%D0%B9_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D1%81%D1%82%D0%B8 

Автор: xvr 24.5.2013, 13:14
Цитата(mrgloom @  24.5.2013,  08:42 Найти цитируемый пост)
и я не понял метод проверить int на переполнение это положить его в double

Наоборот - не класть его в double, а прямо в double и проверять. Double можно сравнить с int, в том числе и с max int, а вот int с max int уже сравнивать поздно  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)