ปัญหา Java Multiple Two numbers กับจำนวนลบ [ซ้ำกัน]

Dec 16 2020

ฉันเพิ่งประสบปัญหาด้านล่างนี้

 public class Main {
    public static void main(String[] args) throws Exception {
        // Your code here!
        int i = -2147483648;
        int j = i * -1;
        
        System.out.println("j="+j);
    }
}

ผลลัพธ์: -2147483648

IDE ออนไลน์พร้อมรหัส: https://paiza.io/projects/e/17lF_6-GltIcyubZv3QoFg?theme=twilight

แต่มันทำงานอย่างไรตามตรรกะที่ฉันต้องการเพื่อให้ได้ 2147483648 เป็นผลลัพธ์ใช่ไหม แล้วฉันได้เลขลบนี้มาได้อย่างไร? เป็นเพราะช่วงจำนวนเต็ม (Integer.MIN_VALUE)? วิธีแก้ไขปัญหานี้

คำตอบ

1 LiveandLetLive Dec 16 2020 at 03:10

ค่าโพสิชันสูงสุดที่intสามารถถือได้นั้น2147483647เกินกว่าที่ค่าจะไปที่ปลายอีกด้านหนึ่ง (กล่าวคือเริ่มจากปลายด้านลบ) คุณสามารถเข้าใจได้จากการสาธิตต่อไปนี้:

public class Main {
    public static void main(String[] args) {
        int i = -2147483648;
        int j = i * -1;

        System.out.println("j=" + j);

        System.out.println(Integer.MAX_VALUE);
        System.out.println(Integer.MAX_VALUE + 1);
        System.out.println(Integer.MIN_VALUE);

        // Some more examples for you to understand this concept better
        System.out.println(Integer.MAX_VALUE + 2);
        System.out.println(Integer.MAX_VALUE + 3);
    }
}

เอาท์พุต:

j=-2147483648
2147483647
-2147483648
-2147483648
-2147483647
-2147483646

หลังจาก-2147483648คูณด้วย-1มันจะกลายเป็น2147483648แต่intตัวแปรไม่สามารถเก็บค่าบวกที่มากขนาดนี้ได้ ดังนั้นมันจะเริ่มต้นจากปลายด้านลบ (เช่นInteger.MIN_VALUE)

1 tibetiroka Dec 16 2020 at 03:09

หมายเลข 2147483648 ไม่มีอยู่ ค่าที่ใหญ่ที่สุดของ int คือ 2147483647 ซึ่งน้อยกว่าผลลัพธ์ที่คุณคาดไว้ 1 รายการ การคูณทำให้เกิดการล้นซึ่งจะ 'ย้อนกลับ' ตัวเลขให้เป็นค่าลบที่น้อยที่สุดและทำการคำนวณต่อจากที่นั่น (ด้วยคำอื่น ๆ : 2147483647 + 1 = -2147483648 (ค่าลบน้อยที่สุด)) เนื่องจากผลลัพธ์จะเป็นเพียง 1 ในค่าสูงสุดจึงไม่จำเป็นต้องมีการดำเนินการเพิ่มเติมและจะส่งคืนค่า int ขั้นต่ำ

หากคุณต้องการแก้ไขปัญหานี้ให้ใช้ "long" แทน "int" สำหรับตัวแปรของคุณ คุณยังสามารถใช้คลาสที่ซับซ้อนมากขึ้นเช่น BigDecimal หรือเขียนฟังก์ชันการคูณที่กำหนดเองสำหรับอาร์เรย์ไบต์

หมายเหตุ: ไม่ว่าคุณจะใช้ตัวเลขประเภทใดตราบเท่าที่หน่วยความจำที่ใช้ในการแสดงตัวเลขมีจำนวน จำกัด คุณสามารถพบปัญหาที่คล้ายกันได้ แม้ว่าในสถานการณ์ปกติจะไม่น่าเกิดขึ้นแม้จะเป็นจำนวนเต็ม 32 บิต (int) ก็ตาม