Java เทียบเท่ากับ long long ที่ไม่ได้ลงนาม?


106

ใน C ++ ฉันสนุกกับการเข้าถึงจำนวนเต็ม 64 บิตที่ไม่ได้ลงชื่อผ่านunsigned long long intหรือผ่านuint64_tหรือผ่านทางตอนนี้ใน Java longs คือ 64 บิตฉันรู้แล้ว อย่างไรก็ตามพวกเขามีการลงนาม

มี long (long) ที่ไม่ได้ลงนามเป็น Java แบบดั้งเดิมหรือไม่? ฉันจะใช้มันได้อย่างไร?


4
หมายเหตุคำตอบที่ยอมรับนั้นล้าสมัยตั้งแต่ Java 8 และใหม่กว่า ดูคำตอบโดย GigaStoreสำหรับคุณลักษณะใหม่ที่คุณสามารถขอให้ Java พิจารณาว่าตัวเลขนั้นไม่ได้ลงนาม ไม่ใช่สำหรับการใช้งานในชีวิตประจำวัน แต่มีประโยชน์เมื่อคุณต้องการ
Basil Bourque

คำตอบ:


55

ฉันไม่เชื่ออย่างนั้น เมื่อคุณต้องการไปให้ใหญ่กว่าการเซ็นชื่อยาวฉันคิดว่าBigIntegerเป็นวิธีเดียวที่จะไป (นอกกรอบ)


17
คำตอบนี้ล้าสมัยเล็กน้อย (โพสต์ในปี 2009) เริ่มต้น Java 8 (เผยแพร่เมื่อเดือนมีนาคม 2014) มีการรองรับสำหรับ Unsigned long ตรวจสอบตัวอย่างที่ฉันโพสต์ไว้ด้านล่างเพื่อเป็นคำตอบ
อมร

140

เริ่มต้น Java 8 มีการสนับสนุนสำหรับความยาวที่ไม่ได้ลงชื่อ (64 บิตที่ไม่ได้ลงชื่อ) วิธีที่คุณสามารถใช้ได้คือ:

Long l1 = Long.parseUnsignedLong("17916881237904312345");

ในการพิมพ์คุณไม่สามารถพิมพ์ l1 ได้ แต่ต้องทำก่อน:

String l1Str = Long.toUnsignedString(l1)

แล้ว

System.out.println(l1Str);

@ j10 Long ul1 = Long.parseUnsignedLong(objScannerInstance.next("\\d+"));ไม่สวยหรูอย่างแน่นอนเพราะไม่มีการตรวจสอบช่วง แต่จะช่วยให้คุณดึงอินพุตตัวเลขที่ยาวซึ่งอาจเป็นไปได้เกินช่วงของการเซ็นชื่อยาว (ใช้ประโยชน์จากความจริงที่Scanner::next(...)สามารถยอมรับทั้งวัตถุ Pattern หรือรูปแบบสตริง)
Spencer D

มันยาก.
Alex78191


7

ไม่มีไม่มี นักออกแบบของ Java บันทึกไว้ว่าพวกเขาไม่ชอบ ints ที่ไม่ได้ลงนาม ใช้BigIntegerแทน ดูคำถามนี้เพื่อดูรายละเอียด


22
ฉันเคารพ Gosling ในสิ่งที่เขาทำ แต่ฉันคิดว่าการป้องกันตัวของเขาโดยไม่มีเจตนาที่ไม่ได้ลงชื่อเป็นหนึ่งในข้อแก้ตัวที่โง่ที่สุดที่ฉันเคยได้ยิน :-) เรามีสิ่งที่น่าตื่นเต้นใน Java มากกว่า ints ที่ไม่ได้ลงนาม ... :-)
Brian Knoblauch

1
Gosling ที่ JavaPolis 2007 ให้ตัวอย่างที่สับสนไม่สามารถใช้ได้กับ ints ที่ไม่ได้ลงนาม Josh Bloch ชี้ให้เห็นว่ามันใช้ไม่ได้กับ ints ที่ลงชื่อเช่นกัน จำนวนเต็มขนาดตามอำเภอใจ ftw!
Tom Hawtin - แทคไลน์


2
@PP: ฉันไม่คิดว่าเป็นไปได้ที่จะกำหนดกฎที่เหมาะสมซึ่งอนุญาตให้มีการโต้ตอบระหว่างประเภทที่ลงชื่อและไม่ได้ลงนามได้อย่างอิสระเมื่ออย่างน้อยหนึ่งในนั้นได้กำหนดพฤติกรรมการห่อ ดังที่ได้กล่าวไปแล้วว่าไบต์ที่ไม่ได้ลงชื่อหรือสั้นที่ไม่ได้ลงชื่อจะทำให้เกิดปัญหาเป็นศูนย์เนื่องจากไบต์ไม่โต้ตอบกับประเภทอื่น ๆ ปัญหาที่ใหญ่กว่าคือการกำหนดพฤติกรรมการตัดสำหรับประเภทที่ใช้แทนตัวเลขซึ่งแตกต่างจากการมีประเภทการตัดแยกต่างหากสำหรับโอกาสที่หายากเหล่านั้น (เช่นการคำนวณแฮชโค้ด) เมื่อพฤติกรรมการตัดมีประโยชน์จริง
supercat

3
@PP: ฉันหวังว่านักออกแบบภาษาจะตระหนักถึงความสำคัญของการแยกแยะตัวเลขจากวงแหวนพีชคณิต (ประเภท "การตัดจำนวนเต็ม" คืออะไร) ตัวเลขขนาดใด ๆ ควรแปลงเป็นแหวนขนาดใด ๆ โดยปริยาย แต่แหวนควรแปลงเป็นตัวเลขผ่านฟังก์ชันหรือผ่านตัวพิมพ์ที่ชัดเจนเป็นตัวเลขขนาดเดียวกันเท่านั้น พฤติกรรมของ C ซึ่งโดยทั่วไปแล้วประเภทที่ไม่ได้ลงชื่อจะทำงานเป็นวงแหวนเกี่ยวกับพีชคณิต แต่บางครั้งการทำงานเป็นตัวเลขอาจเป็นสิ่งที่เลวร้ายที่สุดในโลก ฉันไม่สามารถจับผิดกอสลิงที่ต้องการหลีกเลี่ยงสิ่งนั้นได้แม้ว่าเขาจะใช้วิธีการที่ผิดโดยสิ้นเชิงก็ตาม
supercat

6

Java 8มีชุดของการดำเนินการแบบยาวที่ไม่ได้ลงชื่อซึ่งช่วยให้คุณปฏิบัติกับตัวแปร Long เหล่านั้นได้โดยตรงว่า Long ที่ไม่ได้ลงนามนี่คือตัวแปรที่ใช้กันทั่วไป:

และการบวกการลบและการคูณจะเหมือนกันสำหรับ longs ที่ลงชื่อและไม่ได้ลงชื่อ


2
การดูอย่างรวดเร็วในซอร์สโค้ดบอกให้ฉันระมัดระวังเล็กน้อยกับวิธีการเหล่านี้ เมื่อ longs เป็นลบแน่นอน (กล่าวคือมีความแตกต่างจากกรณีที่ลงนาม) คลาส BigInteger จะถูกใช้ ซึ่งหมายความว่าจะมีการจัดสรร BigIntegers ใหม่ไม่เกิน 8 ตัวซึ่งค่อนข้างมากและประสิทธิภาพลดลงอย่างแน่นอน
Toonijn

4

ขึ้นอยู่กับการดำเนินการที่คุณตั้งใจจะดำเนินการผลลัพธ์จะเหมือนกันมากมีลายเซ็นหรือไม่ได้ลงนาม อย่างไรก็ตามเว้นแต่คุณจะใช้การดำเนินการเล็กน้อยคุณจะต้องใช้ BigInteger


4

สำหรับความยาวที่ไม่ได้ลงนามคุณสามารถใช้คลาสUnsignedLongจากห้องสมุด Guava :

รองรับการดำเนินการต่างๆ:

  • บวก
  • ลบ
  • ครั้ง
  • mod
  • แบ่งโดย

สิ่งที่ดูเหมือนหายไปในขณะนี้คือตัวดำเนินการกะไบต์ หากคุณต้องการสิ่งเหล่านั้นคุณสามารถใช้ BigInteger จาก Java


3

Java ไม่มีประเภทที่ไม่ได้ลงชื่อ ดังที่ได้กล่าวไปแล้วให้ใส่ค่าใช้จ่ายของ BigInteger หรือใช้ JNI เพื่อเข้าถึงโค้ดเนทีฟ


15
ถ่านเป็นค่า 16 บิตที่ไม่ได้ลงนาม;)
Peter Lawrey

2

แพ็กเกจ org.apache.axis.types มีไฟล์

คลาส UnsignedLong

สำหรับ maven:

<dependency>
    <groupId>org.apache.axis</groupId>
    <artifactId>axis</artifactId>
    <version>1.4</version>
</dependency>

0

ดูเหมือนว่าใน Java 8 จะมีการเพิ่มวิธีการบางอย่างลงใน Long เพื่อปฏิบัติกับสินค้าเก่า [ลงนาม] โดยไม่ได้ลงนาม ดูเหมือนจะเป็นวิธีแก้ปัญหา แต่อาจช่วยได้ในบางครั้ง

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