Я роблю модуль неправильно? Тому що в Java -13 % 64
передбачається оцінювати до, -13
але я отримую 51
.
%
є оператором залишку.
Я роблю модуль неправильно? Тому що в Java -13 % 64
передбачається оцінювати до, -13
але я отримую 51
.
%
є оператором залишку.
Відповіді:
Використовуються обидва визначення модуля від’ємних чисел - деякі мови використовують одне визначення, а інші - інше.
Якщо ви хочете отримати від’ємне число для негативних входів, тоді ви можете використовувати це:
int r = x % n;
if (r > 0 && x < 0)
{
r -= n;
}
Подібним чином, якщо ви використовували мову, яка повертає від'ємне число на від'ємне введення, і ви б віддали перевагу позитивному:
int r = x % n;
if (r < 0)
{
r += n;
}
x % y
, А) якщо x
від’ємне, то залишок від’ємне, тобто x % y == -(-x % y)
. Б) знак y
не має ефекту, тобтоx % y == x % -y
Оскільки "математично" обидва правильні:
-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
-13 % 64 = 51
коли я очікував -13
?".
int result = (-5) % 3;
дає -2. int result = (-3) % 5;
дає -3. Загалом, int result = (-a) % b;
дає правильну відповідь, коли | -a | > b. Для того, щоб отримати належний результат, коли | -a | <b ми повинні обернути дільник. int result = ((-a) % b) + b;
за негативне а або int result = (((-a) % b) + b) % b;
за позитивне чи негативне а
Ваш результат неправильний для Java. Будь ласка, вкажіть трохи контексту, як ви до цього дійшли (ваша програма, реалізація та версія Java).
15.17.3 Оператор залишку%
[...]
Операція залишку для операндів, які є цілими числами після двійкового числового просування (§5.6.2), дає таке значення результату, що (a / b) * b + (a% b) дорівнює a.
15.17.2 Оператор підрозділу /
[...]
Ціле ділення округлюється до 0.
Оскільки / округляється до нуля (в результаті чого дорівнює нулю), результат% у цьому випадку повинен бути негативним.
int result = (-5) % 3;
дає -2 int result = (-3) % 5;
дає -3 Загалом, int result = (-a) % b;
дає правильну відповідь, коли | -a | > b Для того, щоб отримати належний результат, коли | -a | <b ми повинні обернути дільник. int result = ((-a) % b) + b;
для негативного a або int result = (((-a) % b) + b) % b;
для позитивного або негативного a.
(-3) % 5
правильним результатом згідно з визначенням є -3
, і правильна реалізація Java повинна давати цей результат.
(-3)%5
справді дає -3
, і якщо ми хочемо позитивний залишок, ми повинні додати до нього 5, і тоді результат буде2
ви можете використовувати
(x % n) - (x < 0 ? n : 0);
((x % k) + k) % k
. (Хоча ваш, мабуть, читабельніший.)
[0, sign(divisor) * divisor)
замість [0, sign(dividend) * divisor)
.
Ваша відповідь - у wikipedia: modulo operation
У ньому сказано, що на Java ознака операції за модулем однакова з ознакою дивіденду. а оскільки ми говоримо про решту операцій ділення, це нормально, то у вашому випадку вона повертає -13, оскільки -13/64 = 0. -13-0 = -13.
EDIT: Вибачте, неправильно зрозумів ваше запитання ... Ви маєте рацію, Java повинна дати -13. Чи можете ви надати більше оточуючого коду?
Модульна арифметика з негативними операндами визначається мовним дизайнером, який може залишити це на мовній реалізації, який може перенести визначення на архітектуру центрального процесора.
Мені не вдалося знайти визначення мови Java.
Завдяки Іштар, специфікація мови Java для оператора залишку% говорить, що знак результату такий самий, як знак чисельника.
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 (чисельник / знаменник)) повинен дати правильний залишок і знак
В останніх версіях Java ви отримуєте -13%64 = -13
. У відповіді завжди буде знак чисельника.
Відповідно до розділу 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);
}
}