Tôi có đang làm sai mô-đun không? Bởi vì trong Java -13 % 64
được cho là để đánh giá -13
nhưng tôi nhận được 51
.
%
là một toán tử phần dư.
Tôi có đang làm sai mô-đun không? Bởi vì trong Java -13 % 64
được cho là để đánh giá -13
nhưng tôi nhận được 51
.
%
là một toán tử phần dư.
Câu trả lời:
Cả hai định nghĩa về môđun của số âm đều được sử dụng - một số ngôn ngữ sử dụng một định nghĩa này và một số ngôn ngữ khác.
Nếu bạn muốn nhận một số âm cho đầu vào âm thì bạn có thể sử dụng điều này:
int r = x % n;
if (r > 0 && x < 0)
{
r -= n;
}
Tương tự như vậy nếu bạn đang sử dụng một ngôn ngữ trả về một số âm trên đầu vào âm và bạn muốn khẳng định:
int r = x % n;
if (r < 0)
{
r += n;
}
x % y
, A) nếu x
là âm thì phần còn lại là âm, tức là x % y == -(-x % y)
. B) dấu hiệu của y
không có hiệu lực tức làx % y == x % -y
Vì "về mặt toán học" cả hai đều đúng:
-13 % 64 = -13 (on modulus 64)
-13 % 64 = 51 (on modulus 64)
Một trong những tùy chọn phải được chọn bởi các nhà phát triển ngôn ngữ Java và họ đã chọn:
dấu của kết quả bằng dấu của cổ tức.
Nói nó trong thông số kỹ thuật Java:
https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.17.3
-13 % 64 = 51
khi tôi mong đợi -13
?".
int result = (-5) % 3;
cho -2. int result = (-3) % 5;
cho -3. Nói chung, int result = (-a) % b;
đưa ra câu trả lời đúng khi | -a | > b. Để có được kết quả thích hợp khi | -a | <b chúng ta nên bọc số chia. int result = ((-a) % b) + b;
cho một tiêu cực hay int result = (((-a) % b) + b) % b;
cho một tích cực hay tiêu cực
Kết quả của bạn là sai đối với Java. Vui lòng cung cấp một số ngữ cảnh mà bạn đến với nó (chương trình, cách triển khai và phiên bản Java của bạn).
15.17.3 Toán tử phần dư%
[...]
Phép toán phần dư cho các toán hạng là số nguyên sau khi thăng hạng số nhị phân (§5.6.2) tạo ra giá trị kết quả sao cho (a / b) * b + (a% b) bằng a.
15.17.2 Toán tử bộ phận /
[...] Phép chia
số nguyên làm tròn về phía 0.
Vì / được làm tròn về phía 0 (kết quả bằng 0), kết quả của% sẽ là số âm trong trường hợp này.
int result = (-5) % 3;
Cho -2 int result = (-3) % 5;
cho -3 Nói chung, int result = (-a) % b;
đưa ra câu trả lời đúng khi | -a | > b Để nhận được kết quả thích hợp khi | -a | <b chúng ta nên bọc số chia. int result = ((-a) % b) + b;
đối với âm a hoặc int result = (((-a) % b) + b) % b;
dương hoặc âm a.
(-3) % 5
, kết quả chính xác theo định nghĩa là -3
, và việc triển khai đúng Java sẽ tạo ra kết quả đó.
(-3)%5
thực sự mang lại cho -3
, và nếu chúng ta muốn thời gian còn lại tích cực chúng ta nên thêm từ 5 đến nó, và sau đó kết quả sẽ là2
bạn có thể dùng
(x % n) - (x < 0 ? n : 0);
((x % k) + k) % k
. (Mặc dù bạn có lẽ là dễ đọc hơn.)
[0, sign(divisor) * divisor)
thay vì [0, sign(dividend) * divisor)
.
Câu trả lời của bạn là trong wikipedia: hoạt động modulo
Nó nói rằng trong Java, dấu hiệu trên hoạt động modulo giống như dấu hiệu của hoạt động cổ tức. và vì chúng ta đang nói về phần còn lại của phép chia là tốt, nó trả về -13 trong trường hợp của bạn, vì -13/64 = 0. -13-0 = -13.
EDIT: Xin lỗi, đã hiểu nhầm câu hỏi của bạn ... Bạn nói đúng, java nên cho -13. Bạn có thể cung cấp thêm mã xung quanh?
Modulo số học với toán hạng âm được xác định bởi nhà thiết kế ngôn ngữ, người có thể để nó cho việc triển khai ngôn ngữ, người có thể trì hoãn định nghĩa cho kiến trúc CPU.
Tôi không thể tìm thấy định nghĩa ngôn ngữ Java.
Cảm ơn Ishtar, Đặc tả ngôn ngữ Java cho Toán tử phần còn lại% nói rằng dấu của kết quả giống như dấu của tử số.
x = x + m = x - m
trong mô đun m
.
như vậy -13 = -13 + 64
trong modulus 64
và -13 = 51
trong modulus 64
.
giả sử Z = X * d + r
, nếu 0 < r < X
sau đó trong phép chia Z/X
chúng ta gọi r
là phần dư.
Z % X
trả về phần còn lại của Z/X
.
Hàm mod được định nghĩa là số lượng mà một số vượt quá bội số nguyên lớn nhất của ước số không lớn hơn số đó. Vì vậy, trong trường hợp của bạn
-13 % 64
bội số nguyên lớn nhất của 64 không vượt quá -13 là -64. Bây giờ, khi bạn trừ -13 khỏi -64, nó bằng 51-13 - (-64) = -13 + 64 = 51
Trong phiên bản Java JDK 1.8.0_05 -13% 64 = -13 của tôi
bạn có thể thử -13- (int (-13/64)) nói cách khác là thực hiện phép chia chuyển thành một số nguyên để loại bỏ phần phân số sau đó trừ khỏi tử số Vì vậy tử số- (int (tử số / mẫu số)) sẽ cho kết quả chính xác phần còn lại và ký tên
Trong phiên bản mới nhất của Java mà bạn nhận được -13%64 = -13
. Câu trả lời sẽ luôn có dấu của tử số.
Theo phần 15.17.3 của JLS, "Phép toán phần còn lại cho các toán hạng là số nguyên sau khi thăng hạng số nhị phân tạo ra giá trị kết quả sao cho (a / b) * b + (a% b) bằng a. Nhận dạng này là số chẵn trong trường hợp đặc biệt, số bị chia là số nguyên âm có độ lớn lớn nhất có thể cho loại của nó và số chia là -1 (phần còn lại là 0). "
Hy vọng rằng sẽ giúp.
Tôi không nghĩ rằng Java trả về 51 trong trường hợp này. Tôi đang chạy Java 8 trên máy Mac và tôi nhận được:
-13 % 64 = -13
Chương trình:
public class Test {
public static void main(String[] args) {
int i = -13;
int j = 64;
System.out.println(i % j);
}
}