ฉันทำโมดูลัสผิดหรือเปล่า? เพราะใน 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
, A) ถ้าเป็นลบที่เหลือเป็นลบคือx
x % y == -(-x % y)
B) สัญญาณ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 | > ข. เพื่อให้ได้ผลลัพธ์ที่เหมาะสมเมื่อ | -a | <b เราควรรวมตัวหาร int result = ((-a) % b) + b;
สำหรับลบ a หรือint result = (((-a) % b) + b) % b;
บวกหรือลบ a
แน่ใจหรือว่ากำลังทำงานใน Java? 'ทำให้ Java ให้ -13% 64 = -13 ตามที่คาดไว้ ราศีปันผล!
ผลลัพธ์ของคุณไม่ถูกต้องสำหรับ Java โปรดระบุบริบทว่าคุณมาถึงมันได้อย่างไร (โปรแกรมการใช้งานและเวอร์ชันของ Java)
15.17.3 ตัวดำเนินการที่เหลือ%
[... ]
การดำเนินการส่วนที่เหลือสำหรับตัวถูกดำเนินการที่เป็นจำนวนเต็มหลังจากการเลื่อนตำแหน่งตัวเลขไบนารี (§5.6.2) จะสร้างค่าผลลัพธ์ที่ (a / b) * b + (a% b) เท่ากับ ก.
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;
สำหรับบวกหรือลบก.
(-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)
คำตอบของคุณอยู่ในวิกิพีเดีย: การทำงานของโมดูโล
มันบอกว่าใน Java เครื่องหมายบนการทำงานของโมดูโลจะเหมือนกับการจ่ายเงินปันผล และเนื่องจากเรากำลังพูดถึงส่วนที่เหลือของการดำเนินการหารก็ใช้ได้ผลตอบแทน -13 ในกรณีของคุณตั้งแต่ -13/64 = 0. -13-0 = -13
แก้ไข: ขออภัยเข้าใจคำถามของคุณผิด ... คุณพูดถูก java ควรให้ -13 คุณสามารถระบุรหัสโดยรอบเพิ่มเติมได้หรือไม่?
การคำนวณทางคณิตศาสตร์ของโมดูโลที่มีตัวถูกดำเนินการเชิงลบถูกกำหนดโดยผู้ออกแบบภาษาซึ่งอาจปล่อยให้เป็นการนำภาษาไปใช้ซึ่งอาจเลื่อนการกำหนดนิยามไปยังสถาปัตยกรรมของ CPU
ฉันไม่พบนิยามภาษา Java
ขอบคุณ Ishtar ข้อกำหนดภาษา Java สำหรับตัวดำเนินการ Remainder%กล่าวว่าเครื่องหมายของผลลัพธ์เหมือนกับเครื่องหมายของตัวเศษ
เพื่อเอาชนะสิ่งนี้คุณสามารถเพิ่ม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 (ตัวเศษ / ตัวส่วน)) ควรให้ถูกต้อง ส่วนที่เหลือและลงชื่อ
ใน 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);
}
}