Czy robię źle moduł? Ponieważ w Javie -13 % 64
ma oceniać, -13
ale dostaję 51
.
%
jest operatorem reszty.
Czy robię źle moduł? Ponieważ w Javie -13 % 64
ma oceniać, -13
ale dostaję 51
.
%
jest operatorem reszty.
Odpowiedzi:
W użyciu są obie definicje modułu liczb ujemnych - niektóre języki używają jednej definicji, a inne drugiej.
Jeśli chcesz uzyskać liczbę ujemną dla ujemnych danych wejściowych, możesz użyć tego:
int r = x % n;
if (r > 0 && x < 0)
{
r -= n;
}
Podobnie, jeśli używasz języka, który zwraca liczbę ujemną na ujemnych danych wejściowych, a wolałbyś dodatnie:
int r = x % n;
if (r < 0)
{
r += n;
}
x % y
, A) jeśli x
jest ujemne, reszta jest ujemna, tj x % y == -(-x % y)
. B) znak y
nie ma efektu, tj.x % y == x % -y
Ponieważ „matematycznie” oba są poprawne:
-13 % 64 = -13 (on modulus 64)
-13 % 64 = 51 (on modulus 64)
Jedna z opcji musiała zostać wybrana przez programistów języka Java i wybrali:
znak wyniku jest równy znakowi dywidendy.
Mówi to w specyfikacji Java:
https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.17.3
-13 % 64 = 51
kiedy się spodziewałem -13
?".
int result = (-5) % 3;
daje -2. int result = (-3) % 5;
daje -3. Ogólnie int result = (-a) % b;
daje właściwą odpowiedź, gdy | -a | > b. Aby uzyskać poprawny wynik, gdy | -a | <b powinniśmy zawinąć dzielnik. int result = ((-a) % b) + b;
dla negatywnych a lub int result = (((-a) % b) + b) % b;
pozytywnych lub negatywnych a
Twój wynik jest nieprawidłowy dla języka Java. Podaj kontekst, w jaki sposób do tego doszedłeś (Twój program, implementacja i wersja Java).
15.17.3 Pozostały operator%
[...]
Operacja reszty dla operandów, które są liczbami całkowitymi po binarnej promocji liczbowej (§5.6.2) daje taką wartość wyniku, że (a / b) * b + (a% b) jest równe za.
15.17.2 Operator oddziału /
[...]
Dzielenie liczb całkowitych zaokrągla w kierunku 0.
Ponieważ / jest zaokrąglane w kierunku zera (co daje zero), wynik% powinien w tym przypadku być ujemny.
int result = (-5) % 3;
daje -2 int result = (-3) % 5;
daje -3 Ogólnie int result = (-a) % b;
daje poprawną odpowiedź, gdy | -a | > b Aby uzyskać poprawny wynik, gdy | -a | <b powinniśmy zawinąć dzielnik. int result = ((-a) % b) + b;
za negatywne a lub int result = (((-a) % b) + b) % b;
pozytywne lub negatywne a.
(-3) % 5
poprawny wynik zgodnie z definicją to -3
, a poprawna implementacja Javy powinna dać ten wynik.
(-3)%5
rzeczywiście daje -3
, a jeśli chcemy dodatniej reszty, powinniśmy dodać do niej 5, a wtedy wynik będzie2
możesz użyć
(x % n) - (x < 0 ? n : 0);
((x % k) + k) % k
. (Chociaż twój jest prawdopodobnie bardziej czytelny.)
[0, sign(divisor) * divisor)
zamiast [0, sign(dividend) * divisor)
.
Twoja odpowiedź jest w Wikipedii: operacja modulo
Mówi, że w Javie znak operacji modulo jest taki sam jak w przypadku dywidendy. a ponieważ mówimy o pozostałej części operacji dzielenia jest w porządku, zwraca ona w twoim przypadku -13, ponieważ -13/64 = 0 -13-0 = -13.
EDYCJA: Przepraszamy, źle zrozumiałem Twoje pytanie ... Masz rację, java powinien dać -13. Czy możesz podać więcej kodu otaczającego?
Arytmetyka modulo z ujemnymi operandami jest definiowana przez projektanta języka, który może pozostawić ją implementacji języka, który może odłożyć definicję do architektury procesora.
Nie mogłem znaleźć definicji języka Java.
Dzięki Ishtar, specyfikacja języka Java dla operatora reszty% mówi, że znak wyniku jest taki sam jak znak licznika.
x = x + m = x - m
w module m
.
tak -13 = -13 + 64
w module 64
i -13 = 51
w module 64
.
załóżmy Z = X * d + r
, że jeśli 0 < r < X
to w dzieleniu Z/X
nazywamy r
resztę.
Z % X
zwraca pozostałą część Z/X
.
Funkcja mod jest definiowana jako wartość, o którą liczba przekracza największą całkowitą wielokrotność dzielnika, która nie jest większa niż ta liczba. Więc w twoim przypadku
-13 % 64
największa całkowita wielokrotność liczby 64, która nie przekracza -13, to -64. Teraz, kiedy odejmiesz -13 od -64, to równa się 51-13 - (-64) = -13 + 64 = 51
W mojej wersji Java JDK 1.8.0_05 -13% 64 = -13
możesz spróbować -13- (int (-13/64)), innymi słowy wykonaj rzut dzielenia na liczbę całkowitą, aby pozbyć się części ułamkowej, a następnie odejmij od licznika Więc licznik- (int (licznik / mianownik)) powinien dać poprawną pozostała i podpisz
W najnowszych wersjach Java otrzymujesz -13%64 = -13
. Odpowiedź zawsze będzie miała znak licznika.
Zgodnie z sekcją 15.17.3 JLS, „Pozostała operacja dla operandów, które są liczbami całkowitymi po binarnej promocji liczbowej, daje taką wartość wyniku, że (a / b) * b + (a% b) jest równe a. Ta tożsamość zachowuje nawet w szczególnym przypadku, gdy dywidenda jest ujemną liczbą całkowitą o największej możliwej wielkości dla swojego typu, a dzielnik wynosi -1 (reszta to 0). "
Mam nadzieję, że to pomoże.
Myślę, że Java nie zwraca w tym przypadku 51. Używam Java 8 na komputerze Mac i otrzymuję:
-13 % 64 = -13
Program:
public class Test {
public static void main(String[] args) {
int i = -13;
int j = 64;
System.out.println(i % j);
}
}