Странное поведение мода в Obj. С - PullRequest
0 голосов
/ 05 августа 2010

У меня есть следующий код:

NSInteger index1 = (stop.timeIndex - 1);  //This will be -1
index1 = index1 % [stop.schedule count];  // [stop.schedule count] = 33

Итак, у меня есть выражение -1% 33. Это должно дать мне 32, но вместо этого дает мне 3 ... Я дважды проверил значения в отладчике. У кого-нибудь есть идеи?

Ответы [ 3 ]

6 голосов
/ 05 августа 2010

В C оператор модуля не работает с отрицательными числами.(Он дает остаток, а не выполняет модульную арифметику, как предполагает его общее название.)

2 голосов
/ 06 августа 2010

C99 говорит в Разделе 6.5.5 Мультипликативные операторы (жирный шрифт):

Результат оператора / является частным от деления первого операнда на второй; результатом оператора % является остаток .В обеих операциях, если значение второго операнда равно нулю, поведение не определено.

При делении целых чисел результатом оператора / является алгебраический коэффициент с любой отброшенной дробной частью.Если частное a/b представимо, выражение (a/b)*b + a%b должно быть равно a.

Это говорит о том, что % является остатком и не использует слово «модуль» для описанияЭто.На самом деле, слово «модуль» встречается только в трех местах в моей копии C99, и все они относятся к библиотеке, а не к какому-либо оператору.

Это не говорит ничего, что требует, чтобы остаток был положительным,Если требуется положительный остаток, то перезапись a%b как (a%b + b) % b будет работать для любого знака a и b и даст положительный ответ за счет дополнительного сложения и деления.Может быть дешевле вычислить его как m=a%b; if (m<0) m+=b; в зависимости от того, дешевле ли пропущенные ветви или дополнительные деления в вашей целевой архитектуре.

Редактировать: Я ничего не знаю о Objective-C.Ваш оригинальный вопрос был помечен C, и все ответы на сегодняшний день отражают язык C, хотя ваш пример, похоже, код Objective-C.Я предполагаю, что знание того, что правда о Си, полезно.

1 голос
/ 05 августа 2010

Результаты использования оператора mod для отрицательных чисел часто бывают неожиданными.Например, это:

#include <stdio.h>

int main() {
    int n = -1 %  33;
    printf( "%d\n", n );
}

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

...