Когда арифметические операции переполняются, они приводят к детерминированной фигуре?

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

Просто для фона я работаю над проектом Visual Studio C++ с некоторыми причудливыми маленькими числами с плавающей запятой, исходящими от некоторых гауссианов, передаваемых из Matlab через calllib, которые дают мне то, что выглядит как переполнение, где экспонента переходит к огромным числам в определенных местах эта матрица. Проблема в том, что когда я перезапускаю свой код, я все еще получаю переполнения, но в разных местах, что заставляет меня задаться вопросом, насколько стабильно и детерминировано поведение переполнения.


person jxramos    schedule 24.07.2015    source источник
comment
С точки зрения языка переполнение целого числа со знаком приводит к неопределенному поведению. Таким образом, конкретная реализация может обеспечить детерминированное поведение. Но другая реализация могла бы вытащить кроликов из шляпы.   -  person jxh    schedule 25.07.2015
comment
Очень хорошо иметь отношение к языковой перспективе, я проведу несколько экспериментов в конце дня, чтобы увидеть, как Visual C++ 2010 ведет себя для чего-то вроде floatmax*floatmax и intmax+intmax.   -  person jxramos    schedule 25.07.2015
comment
Вы можете обвинить свой компилятор или машину, но это никогда не приведет вас ни к чему. Ясно, что реальная проблема заключается в том, что математическая модель полностью сломана и дает бессмысленные результаты.   -  person Hans Passant    schedule 25.07.2015
comment
Вы спрашиваете об «арифметическом переполнении» и помечаете свой вопрос «переполнение с плавающей запятой» и «целочисленное переполнение»? Решайся, потом спрашивай.   -  person Pascal Cuoq    schedule 25.07.2015
comment
@PascalCuoq извините, но вы можете не осознавать ограниченность тегов для использования здесь. Не было ни тега для арифметического переполнения, ни тега для переполнения с плавающей запятой, и только переполнение было связано с некоторыми элементами CSS. Я работаю со значениями с плавающей запятой, поэтому тег с плавающей запятой. Если у вас есть представитель, не стесняйтесь делать несколько тегов, если вы чувствуете, что мои загромождают использованные теги, и я с готовностью их использую.   -  person jxramos    schedule 25.07.2015
comment
Я предполагаю, что еще одна вещь заключается в том, что мне нужно решить, не являются ли как целые числа, так и данные с плавающей запятой переполнением? Я могу выполнять арифметические операции в любом из них, так в чем здесь проблема/противоречие?   -  person jxramos    schedule 25.07.2015


Ответы (2)


Переполнение целых чисел со знаком является неопределенным поведением; может случиться что угодно, даже такие вещи, как сбой вашей программы.

С практической точки зрения, когда компилятор строил вашу программу, он, вероятно, выбрал какое-то детерминированное поведение...

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

person Community    schedule 25.07.2015
comment
Это действительно острая тонкость! Раньше даже не рассматривал такую ​​вариативность. Спасибо, что поделился! Как оказалось, моя неопределенность не связана с моделью или переполнением, а, похоже, связана с связью между Matlab и C++. Со свежим экземпляром Matlab результаты правильные, я снова запускаю сценарий Matlab и получаю странные результаты, а затем снова другие результаты. Закройте Matlab, снова откройте, повторите, та же история. Я довольно запутался в отладке, но было интересно рассмотреть поведение или, скорее, неопределенное поведение переполнения, когда я блуждаю по проблемному пространству. - person jxramos; 25.07.2015

Не могу ответить на этот вопрос исчерпывающе, но решил продемонстрировать небольшой пример, который я сделал. Итак, вот игрушечный пример, созданный в Visual Studio 2010.

#include <climits>
#include <cfloat>

int _tmain( int argc , _TCHAR* argv[] )
{
    // IS OVERFLOW DETERMINISTIC
    int a = INT_MAX;
    int b = a + 10;

    std::cout <<"a="    << a << std::endl;
    std::cout <<"b=a+1="<< b << std::endl;

    double d1 = DBL_MAX ;
    double d2 = 2*d1;
    std::cout <<"d1="     << d1 << std::endl;
    std::cout <<"d2=2*d2="<< d2 << std::endl;

    return 0;
}

А вот несколько обращений к приложению...

C:\Users\me>cd/d C:\Users\me\Documents\Visual Studio 2010\Projects\TestSolution\Debug

C:\Users\me\Documents\Visual Studio 2010\Projects\TestSolution\Debug>TestSolution.exe
a=2147483647
b=a+10=-2147483639
d1=1.79769e+308
d2=2*d2=1.#INF

C:\Users\me\Documents\Visual Studio 2010\Projects\TestSolution\Debug>TestSolution.exe
a=2147483647
b=a+10=-2147483639
d1=1.79769e+308
d2=2*d2=1.#INF

C:\Users\me\Documents\Visual Studio 2010\Projects\TestSolution\Debug>TestSolution.exe
a=2147483647
b=a+10=-2147483639
d1=1.79769e+308
d2=2*d2=1.#INF

C:\Users\me\Documents\Visual Studio 2010\Projects\TestSolution\Debug>TestSolution.exe
a=2147483647
b=a+10=-2147483639
d1=1.79769e+308
d2=2*d2=1.#INF
person jxramos    schedule 25.07.2015