14 ответов:
используются оба определения модуля отрицательных чисел - некоторые языки используют одно определение, а некоторые-другое.
Если вы хотите получить отрицательное число для отрицательных входов, то вы можете использовать это:
int r = x % n; if (r > 0 && x < 0) { r -= n; }аналогично, если вы используете язык, который возвращает отрицательное число на отрицательном входе, и вы предпочли бы положительный:
int r = x % n; if (r < 0) { r += n; }
поскольку "математически" оба верны:
-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
вы уверены, что работаете на Java? потому что Java дает -13 % 64 = -13, как ожидалось. Знак дивидендов!
ваш результат неверен для Java. Пожалуйста, укажите некоторый контекст, как вы пришли к нему (ваша программа, реализация и версия Java).
15.17.3 Оператор Остатка %
[...]
Операция остатка для операндов, которые являются целыми числами после двоичного числового продвижения (§5.6.2), производит значение результата такое, что (a/b)*b+(a%b) равно a.15.17.2 Оператор Деления /
[...]
Целочисленное деление округляется до 0.Так как / округляется до нуля (что приводит к нулю), результат % должен быть отрицательным в этом случае.
ваш ответ в Википедии: работа по модулю
Он говорит, что в Java знак по модулю операции такой же, как у дивидендов. и поскольку мы говорим об остальной части операции деления просто отлично, что он возвращает -13 в вашем случае, так как -13/64 = 0. -13-0 = -13.
EDIT: извините, неправильно понял ваш вопрос...Вы правы, java должен дать -13. Можете ли вы предоставить более окружающий код?
арифметика по модулю с отрицательными операндами определяется разработчиком языка, который может оставить ее для реализации языка, который может отложить определение до архитектуры ЦП.
Я не смог найти определение языка Java.
Спасибо Иштар, спецификация языка Java для Остальных Операторов % говорит о том, что знак результата совпадает со знаком числителя.
чтобы преодолеть это, вы могли бы добавить
64(или независимо от вашей базы модуля) к отрицательному значению, пока оно не станет положительнымint k = -13; int modbase = 64; while (k < 0) { k += modbase; } int result = k % modbase;результат все равно будет в том же классе эквивалентности.
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.
функция mod определяется как сумма, на которую число превышает наибольшее целое число, кратное делителю, которое не больше этого числа. Так что в вашем случае
-13 % 64самое большое целое число, кратное 64, которое не превышает -13, равно -64. Теперь, когда вы вычитаете -13 из -64 он равен 51
-13 - (-64) = -13 + 64 = 51
в моей версии Java JDK 1.8.0_05 -13%64=-13
вы можете попробовать -13-(int(-13 / 64)) другими словами, деление приведено к целому числу, чтобы избавиться от части дроби затем вычесть из числителя Таким образом, числитель - (int (числитель / знаменатель)) должен дать правильный остаток и знак
согласно разделу 15.17.3 JLS, " операция остатка для операндов, которые являются целыми числами после двоичного числового продвижения, дает такое значение результата, что (a / b)*b+(a%b) равно a. Это тождество имеет место даже в частном случае, когда дивиденд является отрицательным целым числом наибольшей возможной величины для его типа, а делитель равен -1 (остаток равен 0)."
надеюсь, что это поможет.
Я не думаю, что Java возвращает 51 в этом случае. Я запускаю Java 8 на Mac, и я получаю:
-13 % 64 = -13программа:
public class Test { public static void main(String[] args) { int i = -13; int j = 64; System.out.println(i % j); } }
Comments