Почему оператор% Java дает результаты, отличные от моего калькулятора, для получения отрицательного дивиденда? - PullRequest
4 голосов
/ 20 сентября 2011

Каким образом на калькуляторе -1 мод 26 = 25, но на С или Java -1 % 26 == -1.Мне нужна программа, которая решает это как калькулятор.Есть ли разница между ними?

Ответы [ 3 ]

6 голосов
/ 20 сентября 2011

Оба ответа (25 и -1) действительны.Просто разные системы имеют разные соглашения.

Тот, который я вижу наиболее распространенным (в математике):

quotient  = floor(x / y)
remainder = x - quotient * y

Где floor() - округление до отрицательной бесконечности.

Это соглашение, которое дает вам ваш калькулятор.(Mathematica также использует это соглашение.)

Я думаю, что большинство языков программирования используют:

quotient  = integerpart(x / y)
remainder = x - quotient * y

Где integerpart() такое же, как (float -> integer) приведение.(округление к нулю)

В некоторых условных обозначениях остаток должен быть одинаковым с одним из операндов.

То же самое относится и к знаку делителя.Разные условности разные.

5 голосов
/ 20 сентября 2011

"Как получилось ...?"

Существует два общих определения операции по модулю. Java выбрал один («тот же знак, что и у дивиденда»), а калькулятор реализует другой; предположительно "тот же знак, что и у делителя", хотя для уверенности вам нужно будет провести несколько экспериментов.

На самом деле, страница Википедии, посвященная операции по модулю , дает 4 разных определения оператора, которые используются разными языками программирования. (И некоторые языки программирования предоставляют вам два оператора с различной семантикой.)

В случае C определение зависит от версии стандарта C, о которой вы говорите. Для ISO C 1999 оператор modulo следует тому же определению, что и Java. Для более ранних версий стандарта C семантика % зависит от реализации

«Есть ли разница между двумя?»

Очевидно, что есть!

«Мне нужна программа, которая решает ее, как калькулятор.»

Не стесняйтесь написать: -).

Но если вы просто хотите узнать, как получить в Java форму "тот же знак, что и у делителя", вот один из способов:

int otherModulus = (a % b) + (a < 0 ? b : 0);  // works for b > 0.

int otherModulus = (a % b) +                   // works for b != 0
                   (b > 0 ? (a < 0 ? b : 0) : (a > 0 ? -b : 0));
3 голосов
/ 20 сентября 2011

Арифметика по модулю с отрицательными операндами различается в разных языках и зависит от определения языка для вождения. В Java Модуль больше похож на Остаток .

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

int r = x % n;
if (r > 0 && x < 0)
{
    r -= n;
}

Или, если вы использовали язык, который возвращает отрицательное число на отрицательном входе, и вы бы предпочли положительное:

int r = x % n;
if (r < 0)
{
    r += n;
}

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

Кроме того, обратите внимание, что то, что должно быть в случае с Java, описано в JLS: в разделе 15.17.3 - Оператор остатка%. Они дают мотивацию (что a% b должно быть таким, что (a / b) * b + (a% b) равно a), но именно включение этого раздела в JLS делает результат таким.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...