Saya mencoba untuk mengkonversi byte yang ditandatangani di unsigned. Masalahnya adalah data yang saya terima tidak ditandatangani dan Java tidak mendukung byte yang tidak ditandatangani, jadi ketika membaca data itu memperlakukannya sebagai ditandatangani.
Saya mencoba untuk mengubahnya dengan solusi berikut yang saya dapatkan dari Stack Overflow.
public static int unsignedToBytes(byte a)
{
int b = a & 0xFF;
return b;
}
Tetapi ketika sekali lagi itu dikonversi dalam byte, saya mendapatkan data yang ditandatangani yang sama. Saya mencoba menggunakan data ini sebagai parameter ke fungsi Java yang hanya menerima byte sebagai parameter, jadi saya tidak bisa menggunakan tipe data lainnya. Bagaimana saya bisa memperbaiki masalah ini?
Jawaban:
Saya tidak yakin saya mengerti pertanyaan Anda.
Saya baru saja mencoba ini dan untuk byte -12 (nilai yang ditandatangani) mengembalikan integer 244 (setara dengan nilai byte yang tidak ditandatangani tetapi diketik sebagai
int
):Apa itu yang ingin kamu lakukan?
Java tidak mengizinkan untuk menyatakan 244 sebagai
byte
nilai, seperti yang akan C. Untuk mengekspresikan bilangan bulat positif di atasByte.MAX_VALUE
(127) Anda harus menggunakan tipe bilangan bulat lainnya, sepertishort
,int
ataulong
.sumber
byte b = (byte)unsignedToBytes((byte) -12);
sekarang coba cetak bFakta bahwa primitif ditandatangani di Jawa tidak relevan dengan bagaimana mereka diwakili dalam memori / transit - byte hanya 8 bit dan apakah Anda mengartikannya sebagai rentang yang ditandatangani atau tidak, itu terserah Anda. Tidak ada bendera ajaib untuk mengatakan "ini ditandatangani" atau "ini tidak ditandatangani".
Ketika primitif ditandatangani, kompiler Java akan mencegah Anda menetapkan nilai lebih tinggi dari +127 ke byte (atau lebih rendah dari -128). Namun, tidak ada yang menghentikan Anda untuk menurunkan int (atau pendek) untuk mencapai hal ini:
sumber
Panduan lengkap untuk bekerja dengan byte yang tidak ditandatangani di Jawa:
Byte tidak bertanda di Java
(Sumber untuk jawaban ini.)
Bahasa Jawa tidak menyediakan apa pun seperti
unsigned
kata kunci. Abyte
sesuai dengan spesifikasi bahasa mewakili nilai antara −128 - 127. Misalnya, jikabyte
dilemparkan keint
Java akan menafsirkan bit pertama sebagai tanda dan menggunakan ekstensi tanda .Yang sedang berkata, tidak ada yang mencegah Anda dari melihat
byte
hanya sebagai 8 bit dan menafsirkan bit-bit itu sebagai nilai antara 0 dan 255. Perlu diingat bahwa tidak ada yang dapat Anda lakukan untuk memaksa interpretasi Anda pada metode orang lain. Jika suatu metode menerima abyte
, maka metode itu menerima nilai antara −128 dan 127 kecuali secara eksplisit dinyatakan sebaliknya.Berikut adalah beberapa konversi / manipulasi yang berguna untuk kenyamanan Anda:
Konversi ke / dari int
(Atau, jika Anda menggunakan Java 8+, gunakan
Byte.toUnsignedInt
.)Parsing / pemformatan
Cara terbaik adalah dengan menggunakan konversi di atas:
Aritmatika
Representasi 2-pelengkap "hanya berfungsi" untuk penambahan, pengurangan, dan penggandaan:
Divisi membutuhkan konversi manual dari operan:
sumber
Tidak ada byte primitif yang tidak ditandatangani di Jawa. Hal yang biasa adalah melemparkannya ke tipe yang lebih besar:
sumber
Saya pikir jawaban lain telah membahas representasi memori dan bagaimana Anda menangani ini tergantung pada konteks bagaimana Anda berencana menggunakannya. Saya akan menambahkan bahwa Java 8 menambahkan beberapa dukungan untuk menangani jenis yang tidak ditandatangani . Dalam hal ini, Anda bisa menggunakannya
Byte.toUnsignedInt
sumber
Catatan tambahan, jika Anda ingin mencetaknya, Anda bisa mengatakannya
sumber
println(b & 0xff)
sudah cukupJika Anda mencari sesuatu seperti ini.
sumber
Adamski memberikan jawaban terbaik, tetapi itu tidak cukup lengkap, jadi bacalah jawabannya, karena menjelaskan detail saya tidak.
Jika Anda memiliki fungsi sistem yang memerlukan byte yang tidak ditandatangani untuk diteruskan, Anda dapat melewati byte yang ditandatangani karena akan secara otomatis memperlakukannya sebagai byte yang tidak ditandatangani.
Jadi, jika fungsi sistem memerlukan empat byte, misalnya, 192 168 0 1 sebagai byte yang tidak ditandatangani, Anda dapat meneruskan -64 -88 0 1, dan fungsi tersebut masih akan berfungsi, karena tindakan meneruskannya ke fungsi akan menghapus tanda tangani mereka .
Namun Anda tidak mungkin memiliki masalah ini karena fungsi sistem tersembunyi di belakang kelas untuk kompatibilitas lintas platform, meskipun beberapa metode baca java.io mengembalikan byte yang tidak ditandai sebagai int.
Jika Anda ingin melihat ini berfungsi, cobalah menulis byte yang ditandatangani ke file dan membacanya kembali sebagai byte yang tidak ditandatangani.
sumber
Anda juga bisa:
Penjelasan:
Katakanlah
a = (byte) 133;
Dalam memori itu disimpan sebagai: "1000 0101" (hex 0x85)
Jadi perwakilannya menerjemahkan unsigned = 133, bertanda = -123 (sebagai pelengkap 2)
Ketika shift kiri dilakukan 24 bit ke kiri, hasilnya sekarang adalah integer 4 byte yang direpresentasikan sebagai:
"10000101 00000000 00000000 00000000" (atau "0x85000000" dalam hex)
maka kita miliki
dan itu bergeser lagi pada 24 bit yang tepat tetapi mengisi dengan nol terkemuka. Jadi hasilnya untuk:
"00000000 00000000 00000000 10000101" (atau "0x00000085" dalam hex)
dan itu adalah representasi yang tidak ditandatangani yang sama dengan 133.
Jika Anda mencoba melakukan cast
a = (int) a;
maka apa yang akan terjadi adalah ia mempertahankan representasi byte 2 dari byte dan menyimpannya sebagai int juga sebagai pelengkap 2's:(int) "10000101" ---> "11111111 11111111 11111111 10000101"
Dan itu diterjemahkan sebagai: -123
sumber
java.lang.Byte.toUnsignedInt(byte value)
. Dan jika Anda belum menggunakan Java 8, tingkatkan ASAP. Java 7 dan sebelumnya adalah akhir dari kehidupan.Ini tidak jauh berbeda dari fungsi yang menerima bilangan bulat yang ingin Anda berikan nilai lebih besar dari 2 ^ 32-1.
Kedengarannya seperti itu tergantung pada bagaimana fungsi didefinisikan dan didokumentasikan; Saya dapat melihat tiga kemungkinan:
Mungkin secara eksplisit mendokumentasikan bahwa fungsi memperlakukan byte sebagai nilai yang tidak ditandatangani, dalam hal ini fungsi tersebut mungkin harus melakukan apa yang Anda harapkan tetapi tampaknya salah diimplementasikan. Untuk case integer, fungsi mungkin akan mendeklarasikan parameter sebagai integer yang tidak ditandatangani, tetapi itu tidak mungkin untuk case byte.
Ini mungkin mendokumentasikan bahwa nilai untuk argumen ini harus lebih besar dari (atau mungkin sama dengan) nol, dalam hal ini Anda menyalahgunakan fungsi (melewati parameter di luar kisaran), berharap untuk melakukan lebih dari yang dirancang untuk melakukan. Dengan beberapa tingkat dukungan debug Anda mungkin mengharapkan fungsi untuk melemparkan pengecualian atau gagal pernyataan.
Dokumentasi mungkin tidak mengatakan apa-apa, dalam hal ini parameter negatif, yah, parameter negatif dan apakah itu memiliki makna tergantung pada apa fungsi tidak. Jika ini tidak berarti maka mungkin fungsi tersebut harus benar-benar didefinisikan / didokumentasikan sebagai (2). Jika ini bermakna dalam cara yang tidak jelas (misalnya nilai-nilai non-negatif digunakan untuk mengindeks ke dalam array, dan nilai-nilai negatif digunakan untuk mengindeks kembali dari akhir array sehingga -1 berarti elemen terakhir) dokumentasi harus mengatakan apa itu berarti dan saya berharap itu bukan apa yang Anda ingin lakukan.
sumber
Jika Anda memiliki fungsi yang harus melewati byte yang ditandatangani, apa yang Anda harapkan untuk dilakukan jika Anda melewati byte yang tidak ditandatangani?
Mengapa Anda tidak bisa menggunakan tipe data lainnya?
Tanpa Anda dapat menggunakan byte sebagai byte yang tidak ditandatangani dengan terjemahan sederhana atau tanpa terjemahan. Itu semua tergantung pada bagaimana itu digunakan. Anda perlu mengklarifikasi apa yang ingin Anda lakukan dengannya.
sumber
Meskipun mungkin tampak menjengkelkan (berasal dari C) bahwa Java tidak memasukkan byte yang tidak ditandatangani dalam bahasa itu sebenarnya bukan masalah besar karena operasi "b & 0xFF" yang sederhana menghasilkan nilai yang tidak ditandatangani untuk (ditandatangani) byte b dalam (jarang) situasi yang sebenarnya dibutuhkan. Bit tidak benar-benar berubah - hanya interpretasi (yang penting hanya ketika melakukan misalnya beberapa operasi matematika pada nilai-nilai).
sumber
x & 0xFF
mana-mana Anda membutuhkannya atau Anda mengulangi sesuatu seperti dibehaveLikeAnUnsignedByte(x)
mana - mana. Ini diperlukan untuk setiap tempat Anda menggunakan nilai byte atau array byte yang perlu ditandatangani, tidak ada cara yang mungkin untuk menghindari pengulangan ini. Anda tidak dapat menulis implementasi protokol yang membaca dan menulis nilai byte dengan hanya satu referensi ke variabel byte. Pandangan sederhana Anda mungkin menjelaskan mengapa mereka tidak pernah peduli untuk memperbaikinya.Tidak ada byte yang tidak ditandatangani di Jawa, tetapi jika Anda ingin menampilkan byte, Anda dapat melakukannya,
Keluaran:
Untuk informasi lebih lanjut, silakan periksa, Cara menampilkan nilai hex / byte di Jawa .
sumber
java.lang.Byte.toUnsignedInt(byte value);
ada untuk ini.Sesuai keterbatasan di Jawa, byte yang tidak ditandatangani hampir tidak mungkin dalam format tipe data saat ini. Anda dapat pergi ke beberapa perpustakaan lain dari bahasa lain untuk apa yang Anda implementasikan dan kemudian Anda dapat memanggil mereka menggunakan JNI .
sumber
Iya dan tidak. Saya sudah menggali sekitar dengan masalah ini. Seperti saya mengerti ini:
Faktanya adalah bahwa java telah menandatangani interger -128 ke 127 .. Dimungkinkan untuk menyajikan unsigned di java dengan:
Jika Anda misalnya menambahkan -12 nomor yang ditandatangani menjadi unsigned Anda mendapatkan 244. Tetapi Anda dapat menggunakan nomor itu lagi di masuk, itu harus digeser kembali ke yang ditandatangani dan itu akan menjadi lagi -12.
Jika Anda mencoba menambahkan 244 ke byte java, Anda akan keluar dariIndexException.
Bersulang..
sumber
java.lang.Byte.toUnsignedInt(byte value);
ada untuk ini.Jika Anda ingin byte yang tidak ditandatangani di Jawa, cukup kurangi 256 dari angka yang Anda minati. Ini akan menghasilkan komplemen dua dengan nilai negatif, yang merupakan angka yang diinginkan dalam byte yang tidak ditandatangani.
Contoh:
Anda perlu menggunakan peretasan yang kotor saat menggunakan leJOS untuk memprogram bata NXT .
sumber
speed_unsigned
sudah ditandatangani. Cetak dan lihat. (Dan- 256
tidak ada yang berhasil di sini.)