การใช้ java.math.BigInteger

| ไอที | Java | 6715

java.math.BigInteger เป็นมาตรฐานหนี่งในคลาสของจาวา

ปัญหาและเหตุผลในการใช้ java.math.BigInteger

การมีช่วงที่ไม่จำกัด ในการทำงานกับข้อมูลจำนวนเต็มชนิด integer หรือ long ที่มีขนาดของข้อมูลที่ใหญ่ เราควรใช้ BigInteger เพราะมันสามารถสร้างจำนวนตัวเลขแบบมากมาย และมีวิธีการ หรือ มีเมดตอด หลายอย่างที่เหมือนกับการดำเนินการกับตัวเลข

การใช้ตัวเลขจะเกิด Overflow ในการคำนวณ ปัญหาที่เกิดขึ้นกับการใช้เลขคณิตเช่น int หรือ long คือ ถ้าค่ามีขนาดใหญ่เกินไป ภาษาจาวา จะทำการเก็บเอาเฉพาะ 32 bit สำหรับ integer หรือ 64 bit สำหรับ long ส่วนที่เหลือจะทำการตัดออกไป ดังตัวอย่างด้านล่าง เราจะเห็นความผิดพลาดจากการใช้ integer และการแก้ไขความผิดพลาดจากการใช้ BigInteger

import java.math.BigInteger;
public class SolutionWithBigInt { 
  public static void main(String[] args) { 
    System.out.println(Integer.MAX_VALUE); 
    int bad = 2000000000; 
    System.out.println("bad = " + bad); 
    System.out.println("bad + 1 = " + (bad + 1)); 
    System.out.println("bad * 3 = " + (bad * 3)); 
    System.out.println("bad * 4 = " + (bad * 4)); 
    BigInteger good = BigInteger.valueOf(2000000000); 
    System.out.println(); 
    System.out.println("good = " + good); 
    System.out.println("good.add(BigInteger.ONE) = " + good.add(BigInteger.ONE)); 
    System.out.println("good.multiply(BigInteger.valueOf(3)) = " + good.multiply(BigInteger.valueOf(3)));
    System.out.println("good.multiply(BigInteger.valueOf(4)) = " + good.multiply(BigInteger.valueOf(4)));
  }
}

utput คือ

2147483647
bad = 2000000000
bad + 1 = 2000000001
bad * 3 = -294967296
bad * 4 = 1705032704

good = 2000000000
good.add(BigInteger.ONE) = 2000000001
good.multiply(BigInteger.valueOf(3)) = 6000000000
good.multiply(BigInteger.valueOf(4)) = 8000000000

จากตัวอย่าง
บรรทัดแรก เราต้อง import java.math.BigInteger; เพื่อที่จะใช้ BigInteger
บรรทัดที่สอง สร้างคลาส ชื่อ SolutionWithBigInt
บรรทัดที่สาม สร้าง method main
บรรทัดที่สี่ แสดงค่าสูงสุดของ Integer โดยใช้คำสั่ง Integer.MAX_VALUE ซึ่งเมื่อรันออกมาจะได้ค่า 2147483647
บรรทัดที่ห้า ประกาศตัวแปรชื่อ bad เป็นตัวแปรชนิด int มีค่าเริ่มต้น 2000000000
บรรทัดที่หก สั่งให้แสดงค่าตัวแปรที่ชื่อ bad
บรรทัดที่เจ็ด สั่งให้แสดงค่า ตัวแปร bad + 1 จะได้ผลลัพธ์แสดงเป็น 2000000001 ซึ่งยังคงถูกต้องอยู่ เพราะ ค่ายังไม่เกินค่าสูงสุด
บรรทัดที่แปด สั่งให้แสดงค่า ตัวแปร bad * 3 จะได้ผลลัพธ์แสดงเป็น -294967296 ซึ่งผลลัพธ์ผิดพลาด เพราะค่าที่คูณกันเสร็จแล้ว มีผลลัพธ์มากกว่า 2147483647
บรรทัดที่เก้า สั่งให้แสดงค่า ตัวแปร bad * 4 จะได้ผลลัพธ์แสดงเป็น 1705032704 ซึ่งมีค่าผิดพลาดเช่นเดียวกับบรรทัดที่ 8
บรรทัดที่สิบ เป็นการประกาศตัวแปรชื่อ good ซึ่งเป็นออบเจ็ค ชนิด BigInteger มีค่าเริ่มต้นเป็น 2000000000
บรรทัดที่สิบเอ็ด เป็นการสั่งให้ขึ้นบรรทัดใหม่
บรรทัดที่สิบสอง เป็นการแสดงค่าของออบเจ็คชื่อ good
บรรทัดที่สิบสาม เป็นการแสดงค่าของออบเจ็ค good + 1 ซึ่งกระทำผ่าน method add จะแสดงค่าเป็น 2000000001
บรรทัดที่สิบสี่ เป็นการแสดงค่าของออบเจ็ค good * 3 ซึ่งกระทำผ่าน method multiply จะแสดงค่าเป็น 6000000000 ซึ่งเป็นค่าที่ถูกต้อง
บรรทัดที่สิบห้า เป็นการแสดงค่าของออบเจ็ค good * 4 ซึ่งกระทำผ่าน method multiply จะแสดงค่าเป็น 8000000000 ซึ่งเป็นค่าที่ถูกต้อง

จากตัวอย่างจะเห็นว่า เราสามารถใช้ BinInteger เพื่อคำนวณตัวเลขต่าง ๆ ที่มีค่ามาก ๆ ได้

ตัวอย่างการใช้งาน BinInteger ที่สำคัญ

import java.math.BigInteger; อันดับแรกก่อนการใช้งาน BinInteger จะต้อง import คลาสขึ้นมาก่อน

การสร้างออบเจ็คชนิด BigInteger เช่น BigInteger bg = new BigInteger("20000000"); การสร้างออบเจ็คจะต้อง ประกาศค่าเริ่มต้นที่เป็นสตริง (ถ้าไม่ใส่ค่าเริ่มต้นจะ error)

การบวก เช่น BigInteger resu = bg.add(BigInteger.valueOf(1)); การบวกโดยใช้ method add

การหาร เช่น BigInteger resu = bg.divide(BigInteger.valueOf(2)); การหารโดยใช้ method divide

การคูณ เช่น BigInteger resu = bg.multiply(BigInteger.valueOf(2)); การคูณโดยใช้ method multiply

การหารเพื่อเอาเศษ เช่น BigInteger resu = bg.mod(BigInteger.valueOf(2)); การหารเอาเศษโดยใช้ method mod

จำนวนตรงข้าม เช่น BigInteger resu = bg.not().add(BigInteger.valueOf(1)); จากตัวอย่าง การเรียกใช้จำนวนตรงข้ามโดยเรียกใช้ method not ค่าที่ได้จะน้อยกว่าจำนวนตรงข้ามอยู่ 1 เสมอ เช่น เราใส่ค่า bg = 20000000 ค่าที่ได้จากการเรียก method not จะได้ -20000001 เพราะฉะนั้น เราจึงต้องบวกหนึ่งด้วยคำสั่ง add(BigInteger.valueOf(1)) หรือ add(BigInteger.ONE) ก็ได้ เพื่อให้ค่าที่ได้ออกมามีค่าเป็นจำนวนตรงข้ามของจำนวนเดิม อย่างถูกต้อง

***สงสัยหรือเปล่าว่า ทำไมผมจึงต้องใส่ BigInteger.valueOf***

เหตุผลก็เพราะว่า การเรียกใช้ method ของ BigInteger จะรับค่าพารามิเตอร์มาเป็น BigInteger และคืนค่าเป็น BigInteger โดยสามารถดูได้จากรูปด้านล่าง



comments