Очень прямо вперед. Код ниже взят из одной из моих функций:
int i, j;
for (i = 0; i < m; i++) {
for (j = 0; j < numberOfVariables; j++) {
if ((j % i) == 0 && i != 0) {
table[i][j] = 1;
}
}
}
Когда я звоню, я получаю исключение с плавающей запятой. За исключением того, что я работаю без плавающей запятой. Так что же происходит?
когда i
ноль, j % i
предполагает деление на ноль, что не допускается.
Чтобы предотвратить это, вам нужно изменить это:
if ((j % i) == 0 && i != 0) {
к этому:
if (i != 0 && (j % i) == 0) {
(пользуясь короткое замыкание поведение &&
: если левый операнд оценивается как false, то правый операнд никогда не будет оцениваться).
Рассмотрим первую итерацию:
if ((j % i) == 0 && i != 0) {
&&
а также ||
всегда будет сначала вычислять левый операнд, и условие будет замкнутым, если условие станет ложным.
Это означает, что когда i != 0
, Это будут оценивать j % i
первый, и так разделить на ноль. Обратите внимание, что деление на ноль — неопределенное поведение.
Вам нужно заменить эту строку на:
if (i != 0 && (j % i) == 0) {
Таким образом, когда i == 0
, (j % i) == 0
не будет оцениваться
Но вместо того, чтобы делать эту проверку, вы не можете просто избежать этого случая? Вы можете просто повторить i
от 1
в m
вместо этого, чтобы вы также могли удалить чек:
for (i = 1; i < m; i++) {
Редактировать: Ваша среда выполнения, утверждающая, что вы столкнулись с исключением с плавающей запятой, вероятно, ошибочна и приняла арифметическое исключение как деление на ноль; или это может быть связано с оптимизацией компилятора. Что-то в этом роде.
Когда вы оцениваете (j % i) == 0
за i=0
в вашем цикле это делится на 0 в фоновом режиме. Отсюда исключение с плавающей точкой.
int i,j;
for (i = 0; i < m; i++) {
for (j = 0; j < numberOfVariables; j++) {
if (i != 0 && (j % i) == 0 ) {
table[i][j] = 1;
}
}
}
Во время выполнения он оценит это i==0
а также пропустить по модулю оценка.
То, что вы делали раньше, оценивали модуль перед проверкой того, что i!=0
,