เราสามารถสร้างไบต์ที่ไม่ได้ลงนามใน Java


185

ฉันพยายามแปลงไบต์ที่ลงนามแล้วในแบบไม่ได้ลงชื่อ ปัญหาคือข้อมูลที่ฉันได้รับไม่ได้ลงนามและ Java ไม่รองรับไบต์ที่ไม่ได้ลงนามดังนั้นเมื่อมันอ่านข้อมูลที่ถือว่าเป็นข้อมูลที่ลงนามแล้ว

ฉันพยายามแปลงมันด้วยวิธีแก้ปัญหาต่อไปนี้ที่ฉันได้รับจาก Stack Overflow

public static int unsignedToBytes(byte a)
{
    int b = a & 0xFF;
    return b;
}

แต่เมื่อมันถูกแปลงเป็นไบต์อีกครั้งฉันจะได้รับข้อมูลที่เซ็นชื่อเหมือนกัน ฉันกำลังพยายามใช้ข้อมูลนี้เป็นพารามิเตอร์ของฟังก์ชันของ Java ที่ยอมรับเฉพาะไบต์เป็นพารามิเตอร์ดังนั้นฉันจึงไม่สามารถใช้ชนิดข้อมูลอื่นได้ ฉันจะแก้ไขปัญหานี้ได้อย่างไร


2
Guava: UnsignedBytes.toint (ค่าไบต์)
jacktrades

20
java.lang.Byte.toUnsignedInt (ค่าไบต์);
themarketka

คำตอบ:


107

ฉันไม่แน่ใจว่าฉันเข้าใจคำถามของคุณ

ฉันเพิ่งลองนี้และสำหรับไบต์ -12 (ค่าลงนาม) มันคืนจำนวนเต็ม 244 (เทียบเท่ากับค่าไบต์ไม่ได้ลงนาม แต่พิมพ์เป็นint):

  public static int unsignedToBytes(byte b) {
    return b & 0xFF;
  }

  public static void main(String[] args) {
    System.out.println(unsignedToBytes((byte) -12));
  }

คุณต้องการทำอะไร

Java ไม่อนุญาตให้แสดง 244 เป็นbyteค่าตามที่จะ C. เพื่อแสดงจำนวนเต็มบวกดังกล่าวข้างต้นByte.MAX_VALUE(127) ที่คุณต้องใช้ชนิดจำนวนเต็มอื่น ๆ เช่นshort, หรือintlong


1
byte b = (byte)unsignedToBytes((byte) -12); ตอนนี้ลองพิมพ์ b
Jigar Joshi

101
ทำไมคุณถึงยอมรับว่านี่เป็นคำตอบที่ถูกต้อง? สิ่งที่มันทำนั้นเหมือนกับวิธีที่คุณพูดถึงในคำถามของคุณ - แปลงไบต์เป็นจำนวนเต็มไม่ได้ลงนาม
Adamski

1
สิ่งสำคัญคือบางครั้งมีค่าลงนามบางครั้งไม่ได้ลงชื่อดังนั้นอาจเป็นเหตุผลที่เขายอมรับคำตอบนี้ (ไบต์) (b & 0xff) ไม่มีความรู้สึกใด ๆ แต่ (ไบต์) (Math.min ((& B 0xff) * 2, 255)) มีความรู้สึกเช่นในกราฟิกคอมพิวเตอร์มันจะทำให้ pixed แทนด้วย ไบต์สว่างขึ้นสองเท่า :-)
iirekm

3
มันอาจถูกเรียกว่า byteToUnsigned ด้วย
Hernán Eche

195

ความจริงที่ว่าดั้งเดิมถูกลงชื่อใน Java ไม่เกี่ยวข้องกับวิธีที่พวกเขาแสดงในหน่วยความจำ / การขนส่ง - byte เป็นเพียง 8 บิตและไม่ว่าคุณจะตีความว่าเป็นช่วงที่ลงนามหรือไม่ขึ้นอยู่กับคุณ ไม่มีการตั้งค่าสถานะเวทย์มนตร์ที่จะพูดว่า "นี่คือการลงนาม" หรือ "นี่คือไม่ได้ลงนาม"

เนื่องจากการลงนามแบบดั้งเดิมนั้นคอมไพเลอร์ Java จะป้องกันคุณจากการกำหนดค่าที่สูงกว่า +127 ให้เป็นไบต์ (หรือต่ำกว่า -128) อย่างไรก็ตามไม่มีสิ่งใดที่จะหยุดคุณให้ลดระดับ int (หรือ short) เพื่อให้บรรลุสิ่งนี้:

int i = 200; // 0000 0000 0000 0000 0000 0000 1100 1000 (200)
byte b = (byte) 200; // 1100 1000 (-56 by Java specification, 200 by convention)

/*
 * Will print a negative int -56 because upcasting byte to int does
 * so called "sign extension" which yields those bits:
 * 1111 1111 1111 1111 1111 1111 1100 1000 (-56)
 *
 * But you could still choose to interpret this as +200.
 */
System.out.println(b); // "-56"

/*
 * Will print a positive int 200 because bitwise AND with 0xFF will
 * zero all the 24 most significant bits that:
 * a) were added during upcasting to int which took place silently
 *    just before evaluating the bitwise AND operator.
 *    So the `b & 0xFF` is equivalent with `((int) b) & 0xFF`.
 * b) were set to 1s because of "sign extension" during the upcasting
 *
 * 1111 1111 1111 1111 1111 1111 1100 1000 (the int)
 * &
 * 0000 0000 0000 0000 0000 0000 1111 1111 (the 0xFF)
 * =======================================
 * 0000 0000 0000 0000 0000 0000 1100 1000 (200)
 */
System.out.println(b & 0xFF); // "200"

/*
 * You would typically do this *within* the method that expected an 
 * unsigned byte and the advantage is you apply `0xFF` only once
 * and than you use the `unsignedByte` variable in all your bitwise
 * operations.
 *
 * You could use any integer type longer than `byte` for the `unsignedByte` variable,
 * i.e. `short`, `int`, `long` and even `char`, but during bitwise operations
 * it would get casted to `int` anyway.
 */
void printUnsignedByte(byte b) {
    int unsignedByte = b & 0xFF;
    System.out.println(unsignedByte); // "200"
}

5
สำหรับการดำเนินการหลายอย่างมันไม่ต่างกัน แต่สำหรับบางการดำเนินการ ทั้งสองวิธีคุณสามารถใช้ไบต์เป็นไม่ได้ลงนามหรือใช้ถ่านที่ไม่ได้ลงนาม
Peter Lawrey

62
การเข้าถึงอาร์เรย์ด้วยตัวเลขที่อาจเป็นลบนั้นไม่เกี่ยวข้อง
สเตฟาน

3
@ สเตฟาน - ฉันหมายถึงไม่เกี่ยวข้องในบริบทของวิธีการที่พวกเขาเป็นตัวแทนในสาย
Adamski

6
ซึ่งค่อนข้างไม่เกี่ยวข้องกับคำถาม เนื่องจากเขากล่าวว่าเขาต้องการส่งผ่านไปยังฟังก์ชันที่ยอมรับพารามิเตอร์ไบต์เท่านั้นไม่สำคัญว่าสภาพอากาศเราตีความว่าเป็นตัวแทนไบต์ของยูนิคอร์น Java จะถือว่าเป็นหมายเลขที่ลงชื่อเสมอซึ่งอาจเป็นปัญหาสำหรับตัวอย่างเมื่อฟังก์ชันนี้ใช้พารามิเตอร์เป็นดัชนี อย่างไรก็ตามเพื่อความเป็นธรรมฉันยังได้ลงคะแนนอีก 2 คำตอบเนื่องจากพวกเขาไม่ตอบคำถามด้วยเช่นกัน
สเตฟาน

2
@Stefan +1 สำหรับคุณ มีความเกี่ยวข้องอย่างยิ่งถ้าคุณใช้ไบต์เพื่อเข้าถึงอาร์เรย์ 256 องค์ประกอบ นี่เป็นตัวอย่างที่ดีเยี่ยมที่แสดงให้เห็นว่าทำไมทุกคนควรเริ่มเรียนรู้ C และ C ++ ก่อนที่จะย้ายไปที่ Java หรือ C #
Gianluca Ghettini

46

คู่มือฉบับสมบูรณ์สำหรับการทำงานกับไบต์ที่ไม่ได้ลงนามใน Java:

ไบต์ที่ไม่ได้ลงนามใน Java

(ที่มาสำหรับคำตอบนี้)


ภาษาจาวาไม่ได้ให้อะไรเหมือนunsignedคำสำคัญ byteตามสเปคภาษาหมายถึงค่าระหว่าง -128 - 127 ตัวอย่างเช่นถ้าbyteถูกโยนไปยังintJava จะตีความบิตแรกเป็นสัญญาณและการใช้เครื่องหมายนามสกุล

ที่ถูกกล่าวว่าไม่มีอะไรป้องกันคุณจากการดูbyteเพียง 8 บิตและตีความบิตเหล่านั้นเป็นค่าระหว่าง 0 และ 255 เพียงจำไว้ว่าไม่มีอะไรที่คุณสามารถทำได้เพื่อบังคับให้การตีความของคุณตามวิธีการของคนอื่น หากวิธีการยอมรับ a byteแล้ววิธีนั้นจะยอมรับค่าระหว่าง −128 และ 127 เว้นแต่จะระบุไว้เป็นอย่างอื่นอย่างชัดเจน

นี่คือการแปลง / กิจวัตรที่มีประโยชน์เพื่อความสะดวกของคุณ:

การแปลงเป็น / จาก int

// From int to unsigned byte
int i = 200;                    // some value between 0 and 255
byte b = (byte) i;              // 8 bits representing that value

// From unsigned byte to int
byte b = 123;                   // 8 bits representing a value between 0 and 255
int i = b & 0xFF;               // an int representing the same value

(หรือถ้าคุณใช้ Java 8+ ให้ใช้Byte.toUnsignedInt)

การแยก / การจัดรูปแบบ

วิธีที่ดีที่สุดคือใช้การแปลงด้านบน:

// Parse an unsigned byte
byte b = (byte) Integer.parseInt("200");

// Print an unsigned byte
System.out.println("Value of my unsigned byte: " + (b & 0xFF));

เลขคณิต

การเป็นตัวแทน 2 ส่วน "เพิ่งได้ผล" สำหรับการบวกการลบและการคูณ:

// two unsigned bytes
byte b1 = (byte) 200;
byte b2 = (byte) 15;

byte sum  = (byte) (b1 + b2);  // 215
byte diff = (byte) (b1 - b2);  // 185
byte prod = (byte) (b2 * b2);  // 225

Division ต้องการการแปลงตัวถูกดำเนินการแบบแมนนวล:

byte ratio = (byte) ((b1 & 0xFF) / (b2 & 0xFF));

1
'char' ไม่ได้แทนตัวเลข
ออกจากระบบ

26
ที่จะนำมันสั้น: คุณกำลังผิด
aioobe

36

ไม่มีไบต์ที่ไม่ได้ลงนามดั้งเดิมใน Java สิ่งปกติคือการโยนให้เป็นประเภทที่ใหญ่กว่า:

int anUnsignedByte = (int) aSignedByte & 0xff;

การโยนไปยัง int จำเป็นหรือไม่
nich

มันอาจจะเป็นนักแสดงโดยนัย แต่ก็มีนักแสดงอย่างใดอย่างหนึ่ง และนักแสดงนั้นก็มีส่วนขยายที่เซ็นชื่อ และนั่นคือปัญหา หากคุณแสดงตัวชัดเจนคุณอย่างน้อยก็สามารถเห็นสิ่งนี้เกิดขึ้น
foo

21

ฉันคิดว่าคำตอบอื่น ๆ ครอบคลุมถึงการเป็นตัวแทนของหน่วยความจำและวิธีที่คุณจัดการกับสิ่งเหล่านี้ขึ้นอยู่กับบริบทของวิธีการใช้งาน ฉันจะเพิ่มว่าJava 8 เพิ่มการสนับสนุนบางส่วนสำหรับการรับมือกับประเภทที่ไม่ได้ลงชื่อ ในกรณีนี้คุณสามารถใช้Byte.toUnsignedInt

int unsignedInt = Byte.toUnsignedInt(myByte);

4

หมายเหตุด้านข้างหากคุณต้องการพิมพ์ออกมาคุณสามารถพูดได้

byte b = 255;
System.out.println((b < 0 ? 256 + b : b));

6
ทำไมจึงซับซ้อน println(b & 0xff)ก็เพียงพอแล้ว
phuclv


0

Adamski ให้คำตอบที่ดีที่สุด แต่ยังไม่สมบูรณ์ดังนั้นโปรดอ่านคำตอบของเขาเนื่องจากอธิบายรายละเอียดที่ฉันไม่ได้

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

ดังนั้นหากฟังก์ชันระบบต้องการสี่ไบต์ตัวอย่างเช่น 192 168 0 1 เป็นไบต์ที่ไม่ได้ลงนามคุณสามารถผ่าน -64 -88 0 1 และฟังก์ชันจะยังคงทำงานได้เนื่องจากการส่งผ่านไปยังฟังก์ชันจะเป็นการยกเลิกการลงชื่อ .

อย่างไรก็ตามคุณไม่น่าจะมีปัญหานี้เนื่องจากฟังก์ชั่นของระบบถูกซ่อนอยู่หลังคลาสเพื่อความเข้ากันได้ข้ามแพลตฟอร์มแม้ว่าบางวิธีการอ่าน java.io จะส่งกลับไบต์ที่ไม่ได้รับผลเป็น int

หากคุณต้องการเห็นการทำงานนี้ให้ลองเขียนไบต์ที่ลงนามแล้วลงในไฟล์แล้วอ่านกลับเป็นไบต์ที่ไม่ได้ลงนาม


1
ไม่มีสิ่งเช่นไบต์ที่ลงนามหรือไม่ได้ลงนาม
Vlastimil Ovčáčík

คุณเขียนและอ่านจำนวนไบต์ในตัวอย่างของคุณอย่างไร
Vlastimil Ovčáčík

0

นอกจากนี้คุณยังสามารถ:

public static int unsignedToBytes(byte a)
{
    return (int) ( ( a << 24) >>> 24);
}    

คำอธิบาย:

สมมติว่า a = (byte) 133;

ในหน่วยความจำจะถูกเก็บเป็น: "1,000 0101" (0x85 เป็น hex)

ดังนั้นการเป็นตัวแทนของมันแปล ไม่ได้ลงนาม = 133, ลงนาม = -123 (เป็นส่วนประกอบ 2 ของ)

<< 24

เมื่อทำการเลื่อนด้านซ้ายไปทางซ้าย 24 บิตผลลัพธ์จะเป็นจำนวนเต็ม 4 ไบต์ซึ่งแสดงเป็น:

"10000101 00000000 00000000 00000000" (หรือ "0x85000000" เป็นเลขฐานสิบหก)

จากนั้นเรามี

(a << 24) >>> 24

และเลื่อนอีกครั้งใน 24 บิตที่ถูกต้อง แต่เติมด้วยเลขศูนย์นำหน้า ดังนั้นจึงส่งผลให้:

"00000000 00000000 00000000 10000101" (หรือ "0x00000085" เป็นเลขฐานสิบหก)

และนั่นคือการแสดงที่ไม่ได้ลงนามซึ่งเท่ากับ 133

หากคุณพยายามที่จะร่ายa = (int) a; แล้วสิ่งที่จะเกิดขึ้นคือมันช่วยให้การแทนค่าส่วนเสริมของ 2 ของไบต์และเก็บไว้เป็น int เช่นเดียวกับส่วนเติมเต็มของ 2:

(int) "10000101" ---> "11111111 11111111 11111111 10000101"

และนั่นแปลว่า: -123


2
ในปี 2562 สิ่งนี้ไม่จำเป็น java.lang.Byte.toUnsignedInt(byte value)ใช้เพียงแค่ และถ้าคุณไม่ได้ใช้ Java 8 ให้อัพเกรด ASAP Java 7 และรุ่นก่อนหน้านี้เป็นจุดสิ้นสุดของชีวิต
สตีเฟ่นซี

0

ฉันกำลังพยายามใช้ข้อมูลนี้เป็นพารามิเตอร์ของฟังก์ชันของ Java ที่ยอมรับเฉพาะไบต์เป็นพารามิเตอร์

สิ่งนี้ไม่แตกต่างจากฟังก์ชั่นที่รับจำนวนเต็มที่คุณต้องการส่งผ่านค่าที่มากกว่า 2 ^ 32-1

ฟังดูเหมือนว่าขึ้นอยู่กับวิธีการกำหนดและบันทึกฟังก์ชัน ฉันเห็นความเป็นไปได้สามประการ:

  1. มันอาจบันทึกเอกสารอย่างชัดเจนว่าฟังก์ชั่นนั้นถือว่าไบต์เป็นค่าที่ไม่ได้ลงนามซึ่งในกรณีนี้ฟังก์ชั่นน่าจะทำในสิ่งที่คุณคาดหวัง แต่ดูเหมือนว่าจะนำไปใช้ผิด สำหรับกรณีจำนวนเต็มฟังก์ชั่นอาจจะประกาศพารามิเตอร์เป็นจำนวนเต็มไม่ได้ลงนาม แต่เป็นไปไม่ได้สำหรับกรณีไบต์

  2. อาจเป็นเอกสารว่าค่าสำหรับอาร์กิวเมนต์นี้จะต้องมากกว่าศูนย์ (หรืออาจเท่ากับ) ซึ่งในกรณีนี้คุณกำลังใช้ฟังก์ชัน (ส่งผ่านพารามิเตอร์นอกขอบเขต) ในทางที่ผิดคาดว่าจะทำมากกว่าที่ออกแบบมา ทำ. ด้วยการสนับสนุนการดีบั๊กบางระดับคุณอาจคาดหวังว่าฟังก์ชั่นนี้จะมีข้อยกเว้นหรือไม่ยืนยัน

  3. เอกสารอาจไม่พูดอะไรเลยในกรณีนี้พารามิเตอร์เชิงลบก็คือพารามิเตอร์เชิงลบและไม่ว่าจะมีความหมายใด ๆ หรือไม่นั้นขึ้นอยู่กับฟังก์ชันที่ใช้ ถ้านี่ไม่มีความหมายแล้วบางทีฟังก์ชันควรถูกกำหนด / จัดทำเป็นเอกสารเป็น (2) หากสิ่งนี้มีความหมายในลักษณะที่ไม่เป็นการรบกวน (เช่นค่าที่ไม่เป็นลบจะถูกใช้เพื่อจัดทำดัชนีในอาร์เรย์และค่าลบจะถูกใช้เพื่อทำดัชนีย้อนกลับจากจุดสิ้นสุดของอาร์เรย์ดังนั้น -1 หมายถึงองค์ประกอบสุดท้าย) เอกสารควรบอกว่าอะไร หมายความว่าและฉันคาดหวังว่ามันไม่ใช่สิ่งที่คุณต้องการให้ทำ


อืมมผมคิดว่าผมเพิ่งโพสต์ตอบกลับที่มีไว้สำหรับคำถามเกี่ยวกับ signedness ไบต์อีก แต่ผมคิดว่ามันก็ยังคงเป็นบิตที่เกี่ยวข้องที่นี่ด้วย ...
เควินมาร์ติน

-1

หากคุณมีฟังก์ชั่นที่ต้องผ่านไบต์ที่ลงนามแล้วคุณคาดหวังว่ามันจะทำอะไรถ้าคุณผ่านไบต์ที่ไม่ได้ลงนาม

ทำไมคุณไม่สามารถใช้ประเภทข้อมูลอื่นได้

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


-1

แม้ว่ามันอาจดูน่ารำคาญ (มาจาก C) ที่ Java ไม่ได้รวมไบต์ที่ไม่ได้ลงนามในภาษา แต่จริงๆแล้วมันไม่ใช่เรื่องใหญ่เพราะการดำเนินการ "b & 0xFF" ง่าย ๆ ทำให้ได้ค่าที่ไม่ได้ลงนามสำหรับ (ลงนาม) byte b ใน (หายาก) สถานการณ์ที่จำเป็นจริงๆ บิตไม่ได้เปลี่ยนแปลงจริง ๆ - แค่การตีความ (ซึ่งสำคัญเมื่อทำเช่นการคำนวณทางคณิตศาสตร์กับค่า)


ดูคำตอบของผู้อื่นคุณคิดว่าคำตอบของคุณดีที่สุด / เป็นประโยชน์หรือไม่ อธิบายเพียงเล็กน้อยและเพิ่มลงในความคิดเห็น
Jubin Patel

8
มันไม่ใช่ของหายากเพียงเพราะคุณไม่ได้เจอมัน ลองใช้โปรโตคอลและคุณจะเจอกับสิ่งนี้เป็นล้านครั้ง สิ่งที่น่ารำคาญคือกรณีการใช้งานส่วนใหญ่ที่ฉันได้พบกับการจัดการกับไบต์คุณต้องการจัดการกับไบต์ที่ไม่ได้ลงนาม (เพราะพวกเขาเป็นไบต์ไม่ใช่ตัวเลข) สิ่งที่บ้าคือการดำเนินการระดับบิตใด ๆ จะแปลงเป็น int ซึ่งหมายถึงค่า "ลบ" ใด ๆ ที่จะแตกต่างอย่างสิ้นเชิงเมื่อขยาย ใช่คุณสามารถหลีกเลี่ยงได้โดยการปิดบังอยู่เสมอ แต่เป็นการเสียเวลาประมวลผลและทำให้เกิดข้อบกพร่องที่ไม่ชัดเจนถ้าคุณลืม
Thor84no

ฉันเห็นด้วยกับ Thor84no: ไบต์ไม่ใช่ตัวเลขและไม่ควรมีเครื่องหมาย ในอีกด้านหนึ่งเนื่องจากไม่ใช่ตัวเลขเราจึงไม่ควรมี / ใช้เครื่องหมาย + และ - การใช้ตัวดำเนินการระดับบิตเท่านั้นทำงานได้ดีในอีกด้านหนึ่งตัวเลื่อนการทำงานจะไม่ทำงานตามที่ต้องการและแน่นอนจาวาจะส่งเสริมไบต์ที่ถูกเลื่อนไปเป็น int
user1708042

1
@ VlastimilOvčáčíkนั่นเป็นไปไม่ได้จริงๆในกรณีนี้นั่นคือสิ่งที่น่ารำคาญ คุณพูดซ้ำx & 0xFFทุกที่ที่คุณต้องการหรือทำซ้ำเหมือนbehaveLikeAnUnsignedByte(x)ทุกที่ นี่เป็นสิ่งจำเป็นสำหรับทุก ๆ ที่ที่คุณใช้ค่าไบต์หรืออาร์เรย์ไบต์ที่จำเป็นต้องมีการลงนามไม่มีวิธีหลีกเลี่ยงการทำซ้ำนี้ คุณไม่สามารถเขียนการใช้โพรโทคอลที่อ่านและเขียนค่าไบต์ด้วยการอ้างอิงเดียวกับตัวแปรไบต์ มุมมองแบบง่าย ๆ ของคุณอาจอธิบายได้ว่าทำไมพวกเขาถึงไม่สนใจที่จะแก้ไข
Thor84no

-1

ไม่มีไบต์ที่ไม่ได้ลงนามใน Java แต่ถ้าคุณต้องการแสดงไบต์คุณสามารถทำได้

int myInt = 144;

byte myByte = (byte) myInt;

char myChar = (char) (myByte & 0xFF);

System.out.println("myChar :" + Integer.toHexString(myChar));

เอาท์พุท:

myChar : 90

สำหรับข้อมูลเพิ่มเติมกรุณาตรวจสอบวิธีการแสดงค่า hex / ไบต์ใน Java


ไม่จำเป็นต้องกำหนดสิ่งนี้ด้วยตนเอง java.lang.Byte.toUnsignedInt(byte value);มีอยู่สำหรับสิ่งนี้
Alexander - Reinstate Monica

-2

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


ฉันไม่คิดว่าเขาต้องการเก็บไว้เป็นไบต์ที่เซ็นชื่อ เขาได้รับมันเป็นไบต์ที่ลงนามแล้วและเขาต้องการเก็บไว้เป็น int ซึ่งใช้ได้อย่างสมบูรณ์แบบ ปัญหาของเขาคือทุกที่ที่เขารับอินพุทจะแสดงค่าระหว่าง 0 และ 255 เป็นไบต์ แต่ Java ตีความว่าในฐานะที่เป็นสองส่วนเติมเต็มค่าลงนามเพราะจาวาไม่สนับสนุนไบต์ที่เซ็นชื่อ
Zac

-2

ใช่และไม่. ฉันขุดมาพร้อมกับปัญหานี้ เช่นฉันเข้าใจสิ่งนี้:

ความจริงก็คือว่าจาวาได้ลงนาม interger -128 ถึง 127 .. มันเป็นไปได้ที่จะนำเสนอที่ไม่ได้ลงชื่อในจาวากับ:

public static int toUnsignedInt(byte x) {
    return ((int) x) & 0xff;
}

หากคุณเช่นเพิ่มหมายเลข -12 ที่ลงนามเพื่อไม่ได้ลงนามคุณจะได้รับ 244 แต่คุณสามารถใช้หมายเลขนั้นได้อีกในการลงชื่อมันจะต้องเปลี่ยนกลับไปเป็นแบบลงนามและจะเป็น -12 อีกครั้ง

หากคุณพยายามเพิ่ม 244 ไปยังจาวาไบต์คุณจะได้รับ outOfIndexException

ไชโย ..


3
ไม่จำเป็นต้องกำหนดสิ่งนี้ด้วยตนเอง java.lang.Byte.toUnsignedInt(byte value);มีอยู่สำหรับสิ่งนี้
Alexander - Reinstate Monica

-3

หากคุณต้องการไบต์ที่ไม่ได้ลงนามใน Java เพียงลบ 256 จากจำนวนที่คุณสนใจมันจะสร้างส่วนเติมเต็มสองด้วยค่าลบซึ่งเป็นจำนวนที่ต้องการในไบต์ที่ไม่ได้ลงนาม

ตัวอย่าง:

int speed = 255; //Integer with the desired byte value
byte speed_unsigned = (byte)(speed-256);
//This will be represented in two's complement so its binary value will be 1111 1111
//which is the unsigned byte we desire.

คุณจำเป็นต้องใช้ hacks สกปรกเช่นเมื่อใช้lejosเพื่อโปรแกรมอิฐ NXT


คุณรู้ไหมว่าค่าไบนารีที่ 255 คือ 1111 1111 ดังนั้นจึงไม่จำเป็นต้องใช้การแทนที่
นิคไวท์

@NickWhite ใช่เป็นเลขฐานสอง แต่คำสั่งของ 2 ใช้จาวาโดยที่ 255 ไม่ใช่ 11111111
XapaJIaMnu

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