xyz ตัวอักษรของประเภท int อยู่นอกช่วง


93

ฉันกำลังทำงานกับชนิดข้อมูลใน Java ในขณะนี้และถ้าฉันเข้าใจถูกต้องประเภทlongจะยอมรับค่าระหว่างช่วง -9,223,372,036,854,775,808 ถึง +9,223,372,036,854,775,807 ตอนนี้อย่างที่คุณเห็นด้านล่างฉันได้สร้างlongตัวแปรที่เรียกว่าtestLongแม้ว่าเมื่อฉันใส่ 9223372036854775807 เป็นค่าฉันได้รับข้อผิดพลาดที่ระบุว่า:

9223372036854775807 ตัวอักษรของประเภท int อยู่นอกช่วง

ฉันไม่รู้ว่าทำไมมันถึงอ้างถึงlongประเภทข้อมูลเป็นintไฟล์.

ใครมีไอเดียบ้าง

รหัส:

char testChar = 01;
byte testByte = -128;
int testInt = -2147483648;
short testShort = -32768;
long testLong = 9223372036854775807;
float testFoat;
double testDouble = 4.940656458412;
boolean testBool = true;

โดยวิธีการ: คุณใช้คอมไพเลอร์อะไร? ทั้ง Eclipse และคอมไพเลอร์ Sun JDK ให้ข้อความแสดงข้อผิดพลาดที่แตกต่างกัน (ในความคิดของฉันดีกว่า) สำหรับปัญหานี้
Joachim Sauer

คำตอบ:


200

เพิ่มทุนLต่อท้าย:

long value = 9223372036854775807L;

มิฉะนั้นคอมไพลเลอร์จะพยายามแยกวิเคราะห์ลิเทอรัลเป็นintข้อความแสดงข้อผิดพลาด


4
มันอยู่ในสเปกภาษา Java ค้นหาข้อความฉบับเต็มได้ที่นี่
Lukas Eder

@ ลูคัสค่ายาว = 00000077029062100L; ทำให้ฉันมีข้อผิดพลาดเดียวกันและมีค่าน้อยกว่า 19 หลัก แนวคิดใด ๆ ว่าทำไมจึงขว้าง "0000007702062100L ตัวอักษรยาวอยู่นอกช่วง"
Brooklynn99

1
@SantosshKumhar: นั่นคือลิเทอรัลฐานแปดซึ่งไม่สามารถมีตัวเลข8หรือ9. ลบเลขศูนย์นำหน้า
Lukas Eder

51

ฉันไม่รู้ว่าทำไมมันถึงอ้างถึงประเภทข้อมูลแบบยาวเป็น int

มันไม่ใช่. คุณควรเรียนรู้ที่จะเชื่อถือข้อความคอมไพเลอร์ (โดยเฉพาะอย่างยิ่งเมื่อมาจากคอมไพเลอร์ที่มีสติทันสมัยและไม่ใช่คอมไพเลอร์ C / C ++ แบบโบราณ) แม้ว่าบางครั้งภาษาที่พวกเขาพูดอาจจะยากที่จะถอดรหัส แต่ก็มักจะไม่โกหกคุณ

ลองดูอีกครั้ง:

ลิเทอรัลของ int 9223372036854775807 อยู่นอกช่วง

โปรดทราบว่ามันไม่ได้กล่าวถึงตัวแปรtestLongหรือประเภทของคุณlongที่ใดก็ได้ดังนั้นจึงไม่เกี่ยวกับการเริ่มต้น ปัญหาดูเหมือนจะเกิดขึ้นที่จุดอื่น

ตอนนี้ให้ตรวจสอบบางส่วนของข้อความ:

  • intบอกเราว่าเขาต้องการที่จะรักษาบางสิ่งให้เป็นintคุณค่า (ซึ่งไม่ใช่สิ่งที่คุณต้องการ!)
  • "อยู่นอกช่วง" ค่อนข้างชัดเจน: มีบางอย่างไม่อยู่ในช่วงที่คาดไว้ (อาจเป็นint)
  • "ตัวอักษร": ตอนนี้ที่น่าสนใจ: ตัวอักษรคืออะไร?

ฉันจะออกจากรายการสบาย ๆ เพื่อพูดคุยเกี่ยวกับตัวอักษรสักครู่: ตัวอักษรคือสถานที่ที่คุณมีค่าในรหัสของคุณ มีStringตัวintอักษรclassตัวอักษรตัวอักษรและอื่น ๆ ทุกครั้งที่คุณพูดถึงค่าอย่างชัดเจนในรหัสของคุณจะเป็นค่าตามตัวอักษร

ดังนั้นมันจึงไม่ได้จู้จี้คุณเกี่ยวกับการประกาศตัวแปร แต่เป็นตัวเลขเองค่าคือสิ่งที่ทำให้คุณจู้จี้

คุณสามารถตรวจสอบได้อย่างง่ายดายโดยใช้ลิเทอรัลเดียวกันในบริบทที่ a longและ an intเป็นที่ยอมรับอย่างเท่าเทียมกัน:

System.out.println(9223372036854775807);

PrintStream.printlnสามารถใช้ทั้งanintหรือalong (หรืออย่างอื่นก็ได้) รหัสนั้นก็น่าจะใช้ได้ใช่ไหม?

เลขที่ดีบางทีมันควรจะเป็น แต่ตามกฎก็คือไม่ดี

ปัญหาคือว่า "ตัวเลขบางอย่าง" ที่ถูกกำหนดให้เป็นintตัวอักษรและดังนั้นจึงต้องintอยู่ในช่วงที่กำหนดโดย

หากคุณต้องการเขียนlongตัวอักษรคุณต้องทำให้ชัดเจนโดยการต่อท้ายL(หรือตัวพิมพ์เล็กlแต่ฉันขอแนะนำให้คุณใช้ตัวแปรตัวพิมพ์ใหญ่เสมอเพราะอ่านง่ายกว่ามากและยากต่อการผิดพลาดสำหรับ a 1)

โปรดทราบว่าปัญหาที่คล้ายกันนี้เกิดขึ้นกับfloat(postfix F/ f) และdouble(postfix D/ d)

หมายเหตุด้านข้าง: คุณจะทราบว่าไม่มีbyteหรือตามshortตัวอักษรและคุณยังสามารถกำหนดค่า (โดยปกติจะเป็นintตัวอักษร) byteและshortตัวแปรได้: ซึ่งเป็นไปได้เนื่องจากกฎพิเศษใน§ 5.2 เกี่ยวกับ Assignment Converson : อนุญาตให้กำหนดนิพจน์คงที่ในประเภทที่ใหญ่กว่า เพื่อbyte, short, charหรือint ถ้าค่าที่อยู่ในประเภทช่วง


3
คุณใช้เวลาจากที่ไหน ;-)
Lukas Eder

3
@Lukas: บางครั้งฉันเขียนคำตอบดังกล่าวด้วยความหวังว่าฉันจะไม่ต้องเขียนคำตอบที่สั้นกว่านี้อีก 300 คำ ;-) นอกจากนี้: การช่วยตีความข้อความแสดงข้อผิดพลาด (หวังว่า) จะมีความหมายน้อยกว่า "ข้อความแสดงข้อผิดพลาดนั้นหมายความว่าอย่างไร" คำถาม
Joachim Sauer

คำตอบของคุณดีมาก ... ไม่ต้องสงสัยเลยนั่นคือเหตุผลที่โหวตขึ้น แต่โปรดแก้ไขและที่ด้านบนสุด (เริ่มต้นคำตอบของคุณ) เพียงเขียนคำตอบที่แน่นอนใน 1 บรรทัดจากนั้นจึงอยู่ใต้คำอธิบายของคุณ เนื่องจากผู้คนจำนวนมากค้นหาวิธีแก้ปัญหาอย่างรวดเร็วมากกว่าคำอธิบายที่ลึกซึ้ง
Shirish Herwade

4
พวกเขามีอิสระที่จะดูคำตอบที่สองอื่น ๆ (คำตอบที่ได้รับคะแนนสูงสุดยังให้คำตอบอย่างรวดเร็ว) ฉันคิดว่าการให้ความรู้ผู้คนเกี่ยวกับวิธีแยกวิเคราะห์และทำความเข้าใจข้อความแสดงข้อผิดพลาดมีประโยชน์ในระยะยาวมากกว่าการทำเพื่อพวกเขา "ให้ปลาผู้ชาย ... " และทั้งหมดนั้น
Joachim Sauer

ขอบคุณสำหรับบันทึกด้านข้าง
Venkatesh Goud


0

ฉันเคยมีปัญหานี้ในอดีตและฉันได้แก้ไขโดยการเขียนค่าในรูปแบบทางวิทยาศาสตร์ ตัวอย่างเช่น:

double val = 9e300;

-2
long ak = 34778754226788444L/l;

ทั้งสองใช้ แต่ครั้งเดียวใช้ตัวพิมพ์ใหญ่ L หรือตัวพิมพ์เล็ก l เท่านั้น

ทำไมต้องใช้ L / l? เนื่องจาก long เป็นส่วนหนึ่งของประเภทข้อมูลหนึ่ง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.