স্বাক্ষরযুক্ত বাইট এবং পিছনে কীভাবে রূপান্তর করবেন


93

আমাকে একটি নম্বরকে স্বাক্ষরবিহীন বাইটে রূপান্তর করতে হবে। সংখ্যাটি সর্বদা 255 এর থেকে কম বা সমান হয় এবং তাই এটি একটি বাইটে মাপসই হয়।

আমার সেই বাইটটিও আবার সেই সংখ্যায় রূপান্তর করতে হবে। আমি জাভাতে কীভাবে এটি করব? আমি বিভিন্ন উপায়ে চেষ্টা করেছি এবং কোনটিই কাজ করে নি। আমি এখন যা করার চেষ্টা করছি তা এখানে:

int size = 5;
// Convert size int to binary
String sizeStr = Integer.toString(size);
byte binaryByte = Byte.valueOf(sizeStr);

এবং এখন সেই বাইটটি আবার সংখ্যায় রূপান্তর করতে:

Byte test = new Byte(binaryByte);
int msgSize = test.intValue();

স্পষ্টতই, এটি কাজ করে না। কিছু কারণে, এটি সর্বদা সংখ্যাটিকে রূপান্তর করে 65। কোনও পরামর্শ?


আমি এই পদ্ধতিটিও চেষ্টা করেছি: crazysquirrel.com/computing/java/basics/… - কাজ করে না।
ডার্কস্কি

উত্তর:


205

একটি বাইট সর্বদা জাভাতে স্বাক্ষরিত হয়। আপনি বাইনারি-ও-এডিং 0xFF দিয়ে এটির স্বাক্ষরবিহীন মান পেতে পারেন, যদিও:

int i = 234;
byte b = (byte) i;
System.out.println(b); // -22
int i2 = b & 0xFF;
System.out.println(i2); // 234

4
এটি বাইটে আপনি যে নম্বর চান তা সঞ্চয় করছে। জাভা এটিকে স্বাক্ষরবিহীন একের চেয়ে একটি স্বাক্ষরযুক্ত নম্বর হিসাবে বিবেচনা করে। তবে প্রতিটি বিট একই হয় যেন এটি একটি স্বাক্ষরবিহীন সংখ্যা। আপনার স্ট্রিংকে বাইটে রূপান্তর করা অন্য, সম্পর্কিত নয়। এটি একটি নতুন প্রশ্নে আলাদাভাবে পোস্ট করুন।
জেবি নিজেট

4
আপনার int ফিরে পেতে getInt ব্যবহার করুন, এবং বাইট হিসাবে ইন্টি রূপান্তর করুন। একটি int একটি int হয়। এটি কোথা থেকে আসে তা বিবেচ্য নয়।
জেবি নিজত

4
জাভা বাইটে স্বাক্ষর রয়েছে? হুজুর, কী ভয়াবহতা।
নায়ারগডস

19
কেন বিটওয়াইস এবং এর 0xFFফলে একটি স্বাক্ষরবিহীন পূর্ণসংখ্যার ফলাফল হয়? কিছু ব্যাখ্যা সত্যিই সহায়ক হবে।
user462455

4
জাভা 8 একই পদ্ধতি ব্যবহার করুন: সার্বজনীন স্ট্যাটিক ইন টু ইউনসাইনড ইন্ট (বাইট এক্স) {রিটার্ন ((ইনট) এক্স) & 0xff; }
ড্যানিয়েল ডি

57

জাভা 8 স্বাক্ষরবিহীন রূপান্তর দ্বারা Byte.toUnsignedIntরূপান্তর byteকরতে সরবরাহ intকরে। ওরাকলের জেডিকে এটিকে কেবল return ((int) x) & 0xff;কার্যকরভাবে প্রয়োগ করা হয়েছে কারণ হটস্পট ইতিমধ্যে এই প্যাটার্নটিকে কীভাবে অনুকূল করা যায় তা বুঝতে পারে তবে এটি অন্য ভিএমগুলিতে অন্তর্ভুক্ত হতে পারে। আরও গুরুত্বপূর্ণ বিষয়, কলটি কী করে তা বোঝার জন্য পূর্বের কোনও জ্ঞানের প্রয়োজন toUnsignedInt(foo)নেই।

সব মিলিয়ে, জাভা 8 রূপান্তর করতে পদ্ধতি প্রদান করে byteএবং shortস্বাক্ষরবিহীন করার intএবং long, এবং intস্বাক্ষরবিহীন করার longbyteস্বাক্ষরবিহীন রূপান্তর করার একটি পদ্ধতি ইচ্ছাকৃতভাবে বাদ দেওয়াshort হয়েছিল কারণ জেভিএম কেবলমাত্র গাণিতিক সরবরাহ করে এবং যাইহোক।intlong

একটি বাইট কোন int ফিরে রূপান্তর করার জন্য, শুধু একটি ঢালাই ব্যবহার করুন: (byte)someInt। ফলে সংকীর্ণ আদিম রূপান্তর শেষ 8 বিট ব্যতীত সমস্ত বাতিল করে দেবে।


7

যদি আপনার কেবলমাত্র একটি প্রত্যাশিত 8-বিট মানকে একটি স্বাক্ষরিত int থেকে একটি স্বাক্ষরবিহীন মানকে রূপান্তর করতে হয়, আপনি সাধারণ বিট শিফটিং ব্যবহার করতে পারেন:

int signed = -119;  // 11111111 11111111 11111111 10001001

/**
 * Use unsigned right shift operator to drop unset bits in positions 8-31
 */
int psuedoUnsigned = (signed << 24) >>> 24;  // 00000000 00000000 00000000 10001001 -> 137 base 10

/** 
 * Convert back to signed by using the sign-extension properties of the right shift operator
 */
int backToSigned = (psuedoUnsigned << 24) >> 24; // back to original bit pattern

http://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html

intবেস টাইপ হিসাবে অন্য কিছু ব্যবহার করে , আপনি অবশ্যই শিফট পরিমাণ সামঞ্জস্য করতে হবে: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

এছাড়াও, মনে রাখবেন যে আপনি byteপ্রকারটি ব্যবহার করতে পারবেন না , এটি করার ফলে অন্যান্য উত্তরদাতাদের দ্বারা উল্লিখিত স্বাক্ষরিত মান হবে। আপনি যদি 8-বিট স্বাক্ষরিত মানটি উপস্থাপন করতে ব্যবহার করতে পারেন তবে সবচেয়ে ছোট আদিমটি হ'ল একটি short


3

Integer.toString(size)আপনার পূর্ণসংখ্যা এর গৃহস্থালির কাজ উপস্থাপনা মধ্যে কল ধর্মান্তরিত, গৃহস্থালির কাজ অর্থাত্ '5'। এই চরিত্রটির ASCII উপস্থাপনা হ'ল 65।

Integer.parseIntমূল ইনট মানটি ফিরে পেতে আপনাকে প্রথমে একটি পূর্ণসংখ্য মানের কাছে স্ট্রিংটি পার্স করতে হবে, উদাহরণস্বরূপ ব্যবহার করে ।

নীচের লাইন হিসাবে, স্বাক্ষরিত / স্বাক্ষরযুক্ত রূপান্তরকরণের জন্য, Stringছবিটি ছেড়ে দেওয়া এবং @ জেবি প্রস্তাবিত হিসাবে বিট ম্যানিপুলেশন ব্যবহার করা ভাল।


এত ভালো? (এখনও এখানে 65 পাচ্ছেন)String sizeStr = Integer.toString(size); int sizeInt = Integer.parseInt(sizeStr); byte binaryByte = Byte.valueOf((byte) sizeInt);
ডার্কস্কি

@ নায়েফক, আপনি আমার মন্তব্য ঠিক তেমনভাবে আপডেট করেছিলেন যেমনটি আপনি আপনার মন্তব্য লিখছেন :-)
পিটার টারিক

ঠিক আছে ধন্যবাদ! কোনও কারণে এটি 65 টি প্রিন্ট করে এখনও। এটার মানে কি? যদি এটি কেবল 65 দেখায়, আসলে বাইটে কী সংরক্ষণ করা হচ্ছে তবে আমি তা পাই না। এছাড়াও দয়া করে আমার প্রশ্নটি দেখুন, আমি এটি সম্পাদনা করেছি এবং স্ট্রিং রূপান্তর সম্পর্কে একটি বিভাগ যুক্ত করেছি :)
ডার্কস্কি

@ নায়েফক আবারও পাঠ্যের অন্তর্ভুক্ত অক্ষরেরString.getBytes() ASCII মান অর্জন করে , সংখ্যার সংখ্যাসূচক মান নয়। আমি উপরের ইঙ্গিত হিসাবে আপনি স্ট্রিং একটি সংখ্যাসম্য মধ্যে পার্স করা প্রয়োজন ।
পিটার তুরিক

4
@ নায়েফসি, যাতে এটি আসলে সম্পূর্ণ আলাদা প্রশ্ন। এবং AFAIS এটি কাজ করা উচিত। রূপান্তরটির আসল ইনপুট এবং আউটপুট এবং কেসটি পুনরুত্পাদন করার জন্য পুরো কোড সহ একটি নতুন প্রশ্ন তৈরি করুন।
পিটার তুরিক

3

সমাধানটি দুর্দান্তভাবে কাজ করে (ধন্যবাদ!), তবে আপনি যদি কাস্টিং এড়াতে এবং জেডিকে নিম্ন স্তরের কাজটি ছেড়ে দিতে চান, আপনি নিজের ইনটি লিখতে একটি ডেটা আউটপুট স্ট্রিম ব্যবহার করতে পারেন এবং এগুলি আবার পড়তে একটি ডেটা ইনপুটস্ট্রিম ব্যবহার করতে পারেন They এগুলি স্বয়ংক্রিয়ভাবে স্বাক্ষরবিহীন হিসাবে গণ্য হবে বাইটস:

ইন্টসকে বাইনারি বাইটে রূপান্তর করার জন্য;

ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos);
int val = 250;
dos.write(byteVal);
...
dos.flush();

এগুলিতে আবার পড়া:

// important to use a (non-Unicode!) encoding like US_ASCII or ISO-8859-1,
// i.e., one that uses one byte per character
ByteArrayInputStream bis = new ByteArrayInputStream(
   bos.toString("ISO-8859-1").getBytes("ISO-8859-1"));
DataInputStream dis = new DataInputStream(bis);
int byteVal = dis.readUnsignedByte();

এসপি বাইনারি ডেটা ফর্ম্যাটগুলি পরিচালনা করার জন্য দরকারী (যেমন ফ্ল্যাট বার্তা ফর্ম্যাট ইত্যাদি)


3

ব্যতীত char, জাভা প্রত্যেক অন্যান্য সংখ্যাসূচক ডাটা টাইপ সাইন ইন করেছেন।

আগের উত্তরে যেমন বলা হয়েছে, আপনি andঅপারেশন করে স্বাক্ষরযুক্ত মানটি পেতে পারেন 0xFF। এই উত্তরে, আমি কীভাবে এটি ঘটে তা ব্যাখ্যা করতে যাচ্ছি।

int i = 234;
byte b = (byte) i;
System.out.println(b);  // -22

int i2 = b & 0xFF;      
// This is like casting b to int and perform and operation with 0xFF

System.out.println(i2); // 234

যদি আপনার মেশিনটি 32-বিট হয়, তবে intডেটা টাইপের মান সংরক্ষণের জন্য 32-বিট দরকার। byteমাত্র 8-বিট দরকার।

intপরিবর্তনশীল iযেমন (ক 32 বিট পূর্ণসংখ্যা হিসাবে) অনুসরণ করে মেমরি প্রতিনিধিত্ব করা হয়।

0{24}11101010

তারপরে byteভেরিয়েবলটি প্রদর্শিত bহয়:

11101010

যেহেতু byteস্বাক্ষরযুক্ত নয়, এই মানটি উপস্থাপন করে -22। (স্মৃতিতে নেতিবাচক পূর্ণসংখ্যার উপস্থাপনা কীভাবে করা যায় সে সম্পর্কে আরও জানতে 2 এর পরিপূরক অনুসন্ধান করুন)

আপনি যদি কাস্ট করেন তবে intএটি এখনও থাকবে -22কারণ ingালাই সংখ্যার চিহ্নটি সংরক্ষণ করে।

1{24}11101010

এর সাথে সম্পাদন করার কাস্ট করা 32-bitমান ।band0xFF

 1{24}11101010 & 0{24}11111111
=0{24}11101010

তাহলে আপনি 234উত্তর হিসাবে পেতে ।


1

যদিও অনেক দেরি হয়ে গেছে তবুও আমি এই বিষয়ে আমার ইনপুটটি দিতে চাই কারণ এটি জেবি নিজেটের প্রদত্ত সমাধান কেন কাজ করে তা পরিষ্কার করে দিতে পারে। বাইট পার্সার নিয়ে কাজ করার এবং নিজেকে রূপান্তর করার জন্য এই ছোট্ট সমস্যায় আমি হোঁচট খেয়েছি। আপনি যখন কোনও বড় আকারের ইন্টিগ্রাল টাইপ থেকে ছোট আকারের ইন্টিগ্রাল টাইপে অনুলিপি করেন তখন এই জাভা ডক বলেছেন যে এটি ঘটে:

https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.3 একটি ইন্টিগ্রাল টাইপ টিতে স্বাক্ষরিত পূর্ণসংখ্যার সংকীর্ণ রূপান্তর কেবলমাত্র সর্বনিম্ন ব্যতীত সমস্ত কিছু বাদ দেয় অর্ডার বিট, যেখানে n টি টাইপ টি উপস্থাপন করতে ব্যবহৃত বিটের সংখ্যা is সংখ্যার মানটির পরিমাণ সম্পর্কে তথ্য সম্ভাব্য ক্ষতি ছাড়াও, ফলাফল ফলাফলের চিহ্নটি ইনপুট মানের চিহ্নের থেকে পৃথক হতে পারে ।

আপনি নিশ্চিত হয়ে উঠতে পারেন যে এই জাভা ডকটি বলেছেন যে বাইট একটি অবিচ্ছেদ্য প্রকার https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html বাইট: বাইট ডেটা টাইপ একটি 8-বিট স্বাক্ষরিত দু'জনের সংখ্যার পরিপূরক

সুতরাং একটি বাইট (8 বিট) এ একটি পূর্ণসংখ্যা (32 বিট) castালার ক্ষেত্রে, আপনি কেবলমাত্র সেই পূর্ণসংখ্যার শেষ (কমপক্ষে 8 টি বিট) প্রদত্ত বাইট ভেরিয়েবলটিতে অনুলিপি করেন।

int a = 128;
byte b = (byte)a; // Last 8 bits gets copied
System.out.println(b);  // -128

গল্পের দ্বিতীয় অংশে জাভা ইউনিারি এবং বাইনারি অপারেটররা অপারেশনগুলিকে কীভাবে প্রচার করে তা জড়িত। https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2 প্রশস্ত আদি রূপান্তর (§5.1.2) উভয় বা উভয় অপারেশনকে নির্দিষ্ট হিসাবে রূপান্তর করতে প্রয়োগ করা হয় নিম্নলিখিত বিধি দ্বারা:

যদি অপরেন্দ্র টাইপ ডাবল হয় তবে অন্যটি ডাবল রূপান্তরিত হয়।

অন্যথায়, যদি অপরেন্দ্র টাইপ ফ্লোটের হয় তবে অন্যটি ফ্লোটে রূপান্তরিত হয়।

অন্যথায়, যদি অপরেন্দ্র টাইপ দীর্ঘ হয়, অন্যটি দীর্ঘ রূপান্তরিত হয়।

অন্যথায়, উভয় অপারেশন টাইপ int তে রূপান্তরিত হয়।

আশ্বস্ত হোন, আপনি যদি ইন্টিগ্রাল টাইপ ইন্ট এবং / বা কম এর সাথে কাজ করছেন তবে এটি কোনও ইনট হিসাবে উন্নীত হবে।

// byte b(0x80) gets promoted to int (0xFF80) by the & operator and then
// 0xFF80 & 0xFF (0xFF translates to 0x00FF) bitwise operation yields 
// 0x0080
a = b & 0xFF;
System.out.println(a); // 128

আমি এটিকে ঘিরে আমার মাথা আঁচড়ালাম :)। রাগটম্যান এর জন্য এখানে একটি ভাল উত্তর আছে। জাভাতে বিটওয়াইজ অপারেটরগুলি কেবল পূর্ণসংখ্যার এবং দীর্ঘ জন্য?


0

আপনি যদি আদিম মোড়কের ক্লাসগুলি ব্যবহার করতে চান তবে এটি কাজ করবে তবে সমস্ত জাভা টাইপগুলি ডিফল্টরূপে স্বাক্ষরিত।

public static void main(String[] args) {
    Integer i=5;
    Byte b = Byte.valueOf(i+""); //converts i to String and calls Byte.valueOf()
    System.out.println(b);
    System.out.println(Integer.valueOf(b));
}

0

বিগইন্টিজারের সাথে বাইটস এবং স্বাক্ষরবিহীন পূর্ণসংখ্যার হ্যান্ডলিং:

byte[] b = ...                    // your integer in big-endian
BigInteger ui = new BigInteger(b) // let BigInteger do the work
int i = ui.intValue()             // unsigned value assigned to i

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.