Как Java делает вычисления модуля с отрицательными числами? - PullRequest
87 голосов
/ 10 декабря 2010

Я неправильно делаю модуль? Потому что в Java -13 % 64 предполагается оценить до -13, но я получаю 51.

Ответы [ 14 ]

98 голосов
/ 10 декабря 2010

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

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

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

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

int r = x % n;
if (r < 0)
{
    r += n;
}
69 голосов
/ 10 декабря 2010

Поскольку «математически» оба верны:

-13 % 64 = -13 (on modulus 64)  
-13 % 64 = 51 (on modulus 64)

Один из вариантов должен был быть выбран разработчиками языка Java, и они выбрали:

знак результатаравно знаку дивиденда.

Говорит это в спецификациях Java:

https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.17.3

19 голосов
/ 09 января 2011

Вы уверены, что работаете в Java? потому что Java дает -13% 64 = -13, как и ожидалось. Знак дивидендов!

14 голосов
/ 10 декабря 2010

Ваш результат неверен для Java.Пожалуйста, предоставьте некоторый контекст того, как вы пришли к нему (ваша программа, реализация и версия Java).

Из Спецификации языка Java

15.17.3 Оператор оставшейся части%[...]Операция остатка для операндов, которые являются целыми числами после двоичного числового продвижения (§5.6.2), производит значение результата, такое, что (a / b) * b + (a% b) равно a.
15.17.2 Оператор подразделения /[...]Целочисленное деление округляет до 0.

Поскольку / округляется до нуля (что приводит к нулю), результат% должен быть отрицательным.

5 голосов
/ 10 декабря 2010

вы можете использовать

(x % n) - (x < 0 ? n : 0);
3 голосов
/ 10 декабря 2010

Ваш ответ в википедии: Операция по модулю

В нем говорится, что в Java знак операции по модулю такой же, как знак дивиденда. и поскольку мы говорим об остальной части операции деления, это нормально, что она возвращает -13 в вашем случае, поскольку -13/64 = 0. -13-0 = -13.

РЕДАКТИРОВАТЬ: Извините, неправильно понял ваш вопрос ... Вы правы, Java должен дать -13. Можете ли вы предоставить больше окружающего кода?

2 голосов
/ 10 декабря 2010

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

Мне не удалось найти определение языка Java.
Спасибо Иштар, Спецификация языка Java для оператора остатка% говорит, что знак результата совпадает со знаком числителя.

1 голос
/ 10 декабря 2010

Функция мода определяется как величина, на которую число превышает наибольшее целое число, кратное делителю, которое не превышает это число Так что в вашем случае

-13 % 64

наибольшее целое число, кратное 64, которое не превышает -13, равно -64. Теперь, когда вы вычитаете -13 из -64, это равняется 51 -13 - (-64) = -13 + 64 = 51

1 голос
/ 10 декабря 2010

Чтобы преодолеть это, вы можете добавить 64 (или независимо от того, какая у вас база модуля) к отрицательному значению, пока оно не станет положительным

int k = -13;
int modbase = 64;

while (k < 0) {
    k += modbase;
}

int result = k % modbase;

Результат все равно будет в том же классе эквивалентности.

1 голос
/ 10 декабря 2010

x = x + m = x - m в модуле m.
поэтому -13 = -13 + 64 по модулю 64 и -13 = 51 по модулю 64.
предположим, Z = X * d + r, если 0 < r < X, то в делении Z/X мы называем r остатком.
Z % X возвращает остаток от Z/X.

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