Здравствуйте AlexeyE, Вы писали:
AE>на си(с++) есть возможность отследить переполнение (напримет при сложении двух значений типа int), полоучить флаги сосояний как на ассемблере?
Сделать соответствующую ассемблерную вставку в сишный код?
Здравствуйте AlexeyE, Вы писали:
AE>на си(с++) есть возможность отследить переполнение (напримет при сложении двух значений типа int), полоучить флаги сосояний как на ассемблере?
Обычно лучше брать с запасом размерность переменных, но уж если так... то
так пойдет?
int a;
int b;
long c;
далее по месту где есть подозрение на переполнение
AE>>на си(с++) есть возможность отследить переполнение?
ПК>Обычно считается, что проще, надежнее и практичнее проверять аргументы перед сложением.
Да нет, как раз проще проверить после сложения. Правда, эта процедура зависит от используемого способа представления отрицательных чисел; но как минимум на большинстве современных машин используется дополнительный код.
Проверку просто выполнять по знакам (старший бит представления). Сложение двух целых с разными знаками никогда не приведет к переполнению. Сложение двух целых одного знака привело к переполнению, если получившийся результат имеет знак, отличный от знака слагаемых.
Здравствуйте achp, Вы писали:
AE>>>на си(с++) есть возможность отследить переполнение?
ПК>>Обычно считается, что проще, надежнее и практичнее проверять аргументы перед сложением.
A>Да нет, как раз проще проверить после сложения. Правда, эта процедура зависит от используемого способа представления отрицательных чисел
Имелся в виду случай с "переносимой" проверкой, т.е. без использования чего-либо за рамками стандарта.
A>Проверку просто выполнять по знакам (старший бит представления). Сложение двух целых с разными знаками никогда не приведет к переполнению. Сложение двух целых одного знака привело к переполнению, если получившийся результат имеет знак, отличный от знака слагаемых.
В этом случае надо еще учитывать, что, например, в следующем фрагменте знак сохраняется (MSVC 32 bit):
...
int i = 610;
char c = 1;
char r = i + c;
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте Павел Кузнецов, Вы писали:
ПК>Здравствуйте achp, Вы писали:
AE>>>>на си(с++) есть возможность отследить переполнение?
ПК>>>Обычно считается, что проще, надежнее и практичнее проверять аргументы перед сложением.
A>>Да нет, как раз проще проверить после сложения. Правда, эта процедура зависит от используемого способа представления отрицательных чисел
ПК>Имелся в виду случай с "переносимой" проверкой, т.е. без использования чего-либо за рамками стандарта.
"Без использования чего-либо за рамками стандарта", если это и можно сделать (не приложу ума, как!), то делать этого не нужно (по целой уйме соображений, начиная от простоты реализации и завершая эффективностью).
Это как раз тот случай, когда переносимость делать самоцелью не нужно; достаточно выделить непереносимый код так, чтобы при необходимости (если таковая вообще возникнет, что в данном случае сомнительно) его можно было приспособить под другую платформу.
Кстати, в принципе ничто не запрещает реализации при выполнении операций над знаковыми целыми в случае переполнения и вовсе кидаться аппаратными исключениями и, вообще, вести себя непристойно .
A>>Проверку просто выполнять по знакам (старший бит представления). Сложение двух целых с разными знаками никогда не приведет к переполнению. Сложение двух целых одного знака привело к переполнению, если получившийся результат имеет знак, отличный от знака слагаемых.
ПК>В этом случае надо еще учитывать, что, например, в следующем фрагменте знак сохраняется (MSVC 32 bit):
ПК>
ПК>...
ПК>int i = 610;
ПК>char c = 1;
ПК>char r = i + c;
ПК>
Ну, здесь имеем сужение типа, это отдельный разговор; я только привел пример (читай ниже: "Далее в том же духе").
Здравствуйте achp, Вы писали:
A>"Без использования чего-либо за рамками стандарта", если это и можно сделать (не приложу ума, как!), то делать этого не нужно (по целой уйме соображений, начиная от простоты реализации и завершая эффективностью).
Скорее, согласен :)
На практике я обычно в соответствующих местах вставляю проверки (иногда достаточно только в _DEBUG) с использованием типов с большим диапазоном. Например:
ASSERT(__int64(i) + j < INT_MAX);
return i + j;
или, еще лучше:
return numeric_cast<int>(__int64(i) + j);
где numeric_cast<Result>(Source source) бросает исключение, если аргумент не может быть корректно представлен типом Result.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
ПК>>где numeric_cast<Result>(Source source) бросает исключение, если аргумент не может быть корректно представлен типом Result.
V>Круто. А этот numeric_cast вообще из какого стандарта? А то у меня ни VC6.0 ни BCB5.0 такого не понимают :-
Я использую свой numeric_cast<>(), что-то в таком же духе есть в <boost/cast.hpp> (www.boost.org)
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен