CodeGym /Java Blog /এলোমেলো /আদিম প্রকারের প্রশস্তকরণ এবং সংকীর্ণকরণ
John Squirrels
লেভেল 41
San Francisco

আদিম প্রকারের প্রশস্তকরণ এবং সংকীর্ণকরণ

এলোমেলো দলে প্রকাশিত
ওহে! আপনি CodeGym এর মাধ্যমে অগ্রসর হওয়ার সাথে সাথে আপনি অনেকবার আদিম প্রকারের সম্মুখীন হয়েছেন। আমরা তাদের সম্পর্কে যা জানি তার একটি সংক্ষিপ্ত তালিকা এখানে রয়েছে:
  1. তারা বস্তু নয় এবং মেমরিতে সঞ্চিত একটি মান প্রতিনিধিত্ব করে
  2. বিভিন্ন ধরনের আছে
    • সম্পূর্ণ সংখ্যা: বাইট , সংক্ষিপ্ত , int , দীর্ঘ
    • ফ্লোটিং-পয়েন্ট (ভগ্নাংশ) সংখ্যা: ভাসমান এবং দ্বিগুণ
    • যৌক্তিক মান: বুলিয়ান
    • প্রতীকী মান (অক্ষর এবং সংখ্যা উপস্থাপনের জন্য): char
  3. প্রতিটি ধরণের মানগুলির নিজস্ব পরিসীমা রয়েছে:

আদিম প্রকার স্মৃতিতে আকার মান পরিসীমা
বাইট 8 বিট -128 থেকে 127
সংক্ষিপ্ত 16 বিট -32768 থেকে 32767
চর 16 বিট 0 থেকে 65536
int 32 বিট -2147483648 থেকে 2147483647
দীর্ঘ 64 বিট -9223372036854775808 থেকে 9223372036854775807
ভাসা 32 বিট (2 থেকে -149-এর ঘাত) থেকে ((2 - (2-এর শক্তি থেকে -23)) * 2 থেকে 127-এর শক্তি)
দ্বিগুণ 64 বিট (-2 থেকে 63 এর শক্তি) থেকে (2 থেকে 63 এর শক্তি) - 1)
বুলিয়ান 8 (যখন অ্যারে ব্যবহার করা হয়), 32 (যদি অ্যারেতে ব্যবহার না করা হয়) সত্য অথবা মিথ্যা
কিন্তু বিভিন্ন মান থাকার পাশাপাশি, তারা মেমরিতে কতটা স্থান দখল করে তার মধ্যেও পার্থক্য রয়েছে। একটি int একটি বাইট বেশী লাগে. এবং একটি দীর্ঘ একটি ছোট থেকে বড়. আদিমদের দ্বারা দখলকৃত মেমরির পরিমাণ রাশিয়ান নেস্টিং পুতুলের সাথে তুলনা করা যেতে পারে: আদিম প্রকারের প্রশস্তকরণ এবং সংকীর্ণকরণ - 2 প্রতিটি বাসা বাঁধার পুতুলের ভিতরে স্থান পাওয়া যায়। বাসা বাঁধার পুতুল যত বড়, সেখানে জায়গা তত বেশি। একটি বড় নেস্টিং পুতুল ( লম্বা ) সহজে একটি ছোট int মিটমাট করা হবে . এটি সহজেই ফিট করে এবং আপনাকে অন্য কিছু করতে হবে না। জাভাতে, আদিমদের সাথে কাজ করার সময়, একে বলা হয় অন্তর্নিহিত রূপান্তর। বা অন্যভাবে করা, এটা প্রশস্ত করা বলা হয়.

জাভাতে প্রসারিত হচ্ছে

এখানে একটি প্রসারিত রূপান্তরের একটি সহজ উদাহরণ:

public class Main {

   public static void main(String[] args) {
      
       int bigNumber = 10000000;

       byte littleNumber = 16;

       bigNumber = littleNumber;
       System.out.println(bigNumber);
   }
}
এখানে আমরা একটি int ভেরিয়েবলের জন্য একটি বাইট মান নির্ধারণ করি । অ্যাসাইনমেন্ট কোনো সমস্যা ছাড়াই সফল হয়: একটি বাইটে সংরক্ষিত মান একটি int মিটমাট করতে পারে তার চেয়ে কম মেমরি নেয়। ছোট নেস্টিং ডল (বাইট মান) সহজেই বড় নেস্টিং ডল ( int পরিবর্তনশীল) এর ভিতরে ফিট করে। আপনি যদি বিপরীতটি করার চেষ্টা করেন তবে এটি একটি ভিন্ন বিষয়, যেমন একটি ভেরিয়েবলের মধ্যে একটি বড় মান স্থাপন করা যার পরিসর এত বড় ডেটা টাইপ মিটমাট করতে পারে না। বাস্তব নেস্টিং পুতুল সঙ্গে, সংখ্যা সহজভাবে মাপসই করা হবে না. জাভা দিয়ে, এটা করতে পারে, কিন্তু সূক্ষ্মতার সাথে। চলুন একটি সংক্ষিপ্ত পরিবর্তনশীল মধ্যে একটি int নির্বাণ চেষ্টা করা যাক :

public static void main(String[] args) {

   int bigNumber = 10000000;
  
   short littleNumber = 1000;

   littleNumber = bigNumber;// Error!
   System.out.println(bigNumber);
}
ত্রুটি! কম্পাইলার বুঝতে পারে যে আপনি একটি ছোট ( ছোট ) ভিতরে একটি বড় নেস্টিং ডল ( int ) ধাক্কা দিয়ে অস্বাভাবিক কিছু করার চেষ্টা করছেন । এই ক্ষেত্রে, সংকলন ত্রুটি কম্পাইলার থেকে একটি সতর্কতা: "আরে, আপনি কি একেবারে নিশ্চিত যে আপনি এটি করতে চান?" আপনি যদি নিশ্চিত হন, তাহলে আপনি কম্পাইলারকে বলুন: "সবকিছু ঠিক আছে। আমি জানি আমি কি করছি!" এই প্রক্রিয়াটিকে বলা হয় স্পষ্ট ধরনের রূপান্তর, বা সংকীর্ণকরণ।

জাভাতে সংকুচিত হচ্ছে

একটি সংকীর্ণ রূপান্তর সম্পাদন করতে, আপনাকে স্পষ্টভাবে নির্দেশ করতে হবে যে ধরণটি আপনি আপনার মানকে রূপান্তর করতে চান৷ অন্য কথায়, আপনাকে কম্পাইলারের প্রশ্নের উত্তর দিতে হবে: "আচ্ছা, এই ছোট নেস্টিং পুতুলগুলির মধ্যে আপনি এই বড় নেস্টিং পুতুলটি কোনটিতে রাখতে চান?" আমাদের ক্ষেত্রে, এটি এই মত দেখায়:

public static void main(String[] args) {

   int bigNumber = 10000000;

   short littleNumber = 1000;

   littleNumber = (short) bigNumber;
   System.out.println(littleNumber);
}
আমরা স্পষ্টভাবে ইঙ্গিত করি যে আমরা একটি সংক্ষিপ্ত পরিবর্তনশীলের মধ্যে একটি int লাগাতে চাই এবং আমরা দায়িত্ব নেব। একটি সংকীর্ণ টাইপ স্পষ্টভাবে নির্দেশিত হয়েছে তা দেখে, কম্পাইলার রূপান্তরটি সম্পাদন করে। ফলাফল কি? কনসোল আউটপুট: -27008 এটি একটু অপ্রত্যাশিত ছিল। কেন আমরা ঠিক যে পেয়েছিলাম? আসলে, এটা সব খুব সহজ. মূলত, মানটি ছিল 10000000 এটি একটি int ভেরিয়েবলে সংরক্ষণ করা হয়েছিল, যা 32 বিট দখল করে। এটি তার বাইনারি উপস্থাপনা:
আদিম প্রকারের প্রশস্তকরণ এবং সংকীর্ণকরণ - 3
আমরা এই মানটিকে একটি সংক্ষিপ্ত ভেরিয়েবলে লিখি , যা শুধুমাত্র 16 বিট সংরক্ষণ করতে পারে! তদনুসারে, আমাদের সংখ্যার শুধুমাত্র প্রথম 16 বিট সেখানে সরানো হবে। বাকিগুলো বাতিল করা হবে। ফলস্বরূপ, সংক্ষিপ্ত চলক নিম্নলিখিত মান গ্রহণ করে
আদিম প্রকারের প্রশস্তকরণ এবং সংকীর্ণকরণ - 4
যেটি দশমিক আকারে -27008 এর সমান তাই কম্পাইলার আপনাকে একটি নির্দিষ্ট প্রকারে একটি স্পষ্ট সংকীর্ণ রূপান্তর নির্দেশ করে "নিশ্চিত" করতে বলে। প্রথমত, এটি দেখায় যে আপনি ফলাফলের জন্য দায়িত্ব নিচ্ছেন। এবং দ্বিতীয়, এটি কম্পাইলারকে বলে যে রূপান্তর করার সময় কতটা স্থান বরাদ্দ করতে হবে। সর্বোপরি, শেষ উদাহরণে, যদি আমরা একটি সংক্ষিপ্ত না হয়ে একটি বাইট ভেরিয়েবলের জন্য একটি int মান বরাদ্দ করি , তাহলে আমাদের নিষ্পত্তিতে শুধুমাত্র 8 বিট থাকবে, 16 নয়, এবং ফলাফলটি ভিন্ন হবে। ভগ্নাংশ প্রকারের ( ফ্লোট এবং ডবল ) রূপান্তর সংকীর্ণ করার জন্য তাদের নিজস্ব প্রক্রিয়া রয়েছে। আপনি যদি একটি পূর্ণসংখ্যার প্রকারে একটি উপদলীয় সংখ্যা কাস্ট করার চেষ্টা করেন, ভগ্নাংশটি বাতিল করা হবে।

public static void main(String[] args) {

   double d = 2.7;

   long x = (int) d;
   System.out.println(x);
}
কনসোল আউটপুট: 2

চর

আপনি ইতিমধ্যেই জানেন যে চারটি পৃথক অক্ষর প্রদর্শন করতে ব্যবহৃত হয়।

public static void main(String[] args) {

   char c = '!';
   char z = 'z';
   char i = '8';
  
}
কিন্তু এই ডেটা টাইপের বেশ কিছু বৈশিষ্ট্য রয়েছে যা বোঝা গুরুত্বপূর্ণ। আসুন আবার মান পরিসরের টেবিলটি দেখি:
আদিম প্রকার স্মৃতিতে আকার মান পরিসীমা
বাইট 8 বিট -128 থেকে 127
সংক্ষিপ্ত 16 বিট -32768 থেকে 32767
চর 16 বিট 0 থেকে 65536
int 32 বিট -2147483648 থেকে 2147483647
দীর্ঘ 64 বিট -9223372036854775808 থেকে 9223372036854775807
ভাসা 32 বিট (2 থেকে -149-এর ঘাত) থেকে ((2 - (2-এর শক্তি থেকে -23)) * 2 থেকে 127-এর শক্তি)
দ্বিগুণ 64 বিট (-2 থেকে 63 এর শক্তি) থেকে (2 থেকে 63 এর শক্তি) - 1)
বুলিয়ান 8 (যখন অ্যারে ব্যবহার করা হয়), 32 (যদি অ্যারেতে ব্যবহার না করা হয়) সত্য অথবা মিথ্যা
0 থেকে 65536 পরিসরটি চর প্রকারের জন্য নির্দেশিত। কিন্তু এর মানে কি? সর্বোপরি, একটি অক্ষর শুধুমাত্র সংখ্যার প্রতিনিধিত্ব করে না, অক্ষর, বিরাম চিহ্নগুলিও উপস্থাপন করে... ব্যাপারটি হল জাভাতে অক্ষরের মানগুলি ইউনিকোড ফর্ম্যাটে সংরক্ষণ করা হয়। আমরা ইতিমধ্যেই পূর্ববর্তী পাঠগুলির একটিতে ইউনিকোডের সম্মুখীন হয়েছি। আপনি সম্ভবত মনে রাখবেন যে ইউনিকোড একটি অক্ষর এনকোডিং মান যা বিশ্বের প্রায় সমস্ত লিখিত ভাষার প্রতীক অন্তর্ভুক্ত করে। অন্য কথায়, এটি বিশেষ কোডের একটি তালিকা যা যেকোনো ভাষার প্রায় প্রতিটি অক্ষরকে উপস্থাপন করে। পুরো ইউনিকোড টেবিলটি অনেক বড়, এবং অবশ্যই, এটি হৃদয় দিয়ে শেখার দরকার নেই। এখানে এটির একটি ছোট অংশ রয়েছে: আদিম প্রকারের প্রশস্তকরণ এবং সংকীর্ণকরণ - 5 প্রধান জিনিস হল কিভাবে অক্ষর সংরক্ষণ করা হয় তা বোঝা, এবং মনে রাখা যে আপনি যদি একটি নির্দিষ্ট অক্ষরের কোড জানেন তবে আপনি সর্বদা আপনার প্রোগ্রামে সেই অক্ষরটি তৈরি করতে পারেন। আসুন কিছু র্যান্ডম সংখ্যা দিয়ে চেষ্টা করি:

public static void main(String[] args) {

   int x = 32816;

   char c = (char) x ;
   System.out.println(c);
}
কনসোল আউটপুট: 耰 এটি জাভাতে char s সংরক্ষণ করতে ব্যবহৃত বিন্যাস । প্রতিটি প্রতীক একটি সংখ্যার সাথে মিলে যায়: একটি 16-বিট (দুই-বাইট) সংখ্যাসূচক কোড। ইউনিকোডে, 32816 চীনা অক্ষর 耰 এর সাথে মিলে যায়। নিম্নলিখিত পয়েন্ট নোট করুন. এই উদাহরণে, আমরা একটি int ভেরিয়েবল ব্যবহার করেছি। এটি মেমরিতে 32 বিট দখল করে, যখন একটি অক্ষর 16 দখল করে। এখানে আমরা একটি int বেছে নিয়েছি, কারণ আমাদের সংখ্যা (32816) সংক্ষিপ্তভাবে ফিট হবে না । যদিও একটি গৃহস্থালির আকার (শুধু একটি ছোট ) 16 বিট, তবে গৃহস্থালির পরিসরে কোন ঋণাত্মক সংখ্যা নেই , তাই চরটির "ধনাত্মক" অংশপরিসর দ্বিগুণ বড় ( ছোট ধরনের জন্য 32767 এর পরিবর্তে 65536)। যতক্ষণ আমাদের কোড 65536-এর নিচে থাকে ততক্ষণ আমরা একটি int ব্যবহার করতে পারি। কিন্তু আপনি যদি 65536-এর চেয়ে বেশি একটি int মান তৈরি করেন, তাহলে এটি 16 বিটের বেশি দখল করবে। এবং এর ফলে একটি সংকীর্ণ রূপান্তর হবে

char c = (char) x;
অতিরিক্ত বিটগুলি বাতিল করা হবে (উপরে আলোচনা করা হয়েছে) এবং ফলাফলটি বেশ অপ্রত্যাশিত হবে।

অক্ষর এবং পূর্ণসংখ্যা যোগ করার বিশেষ বৈশিষ্ট্য

আসুন একটি অস্বাভাবিক উদাহরণ দেখি:

public class Main {

   public static void main(String[] args) {

      char c = '1';

      int i = 1;

       System.out.println(i + c);
   }
}
কনসোল আউটপুট: 50 O_О এটি কীভাবে বোঝায়? 1+1। 50 কোথা থেকে এলো?! আপনি ইতিমধ্যেই জানেন যে charমানগুলি 0 থেকে 65536 পর্যন্ত পরিসরের সংখ্যা হিসাবে মেমরিতে সংরক্ষণ করা হয় এবং এই সংখ্যাগুলি একটি অক্ষরের একটি ইউনিকোড উপস্থাপনা৷ আদিম প্রকারের প্রশস্তকরণ এবং সংকীর্ণকরণ - 6 যখন আমরা একটি অক্ষর এবং কিছু পূর্ণ-সংখ্যা টাইপ যোগ করি, তখন অক্ষরটি সংশ্লিষ্ট ইউনিকোড নম্বরে রূপান্তরিত হয়। আমাদের কোডে, যখন আমরা 1 এবং '1' যোগ করেছি, তখন '1' প্রতীকটি তার নিজস্ব কোডে রূপান্তরিত হয়েছিল, যা 49 (আপনি উপরের টেবিলে এটি যাচাই করতে পারেন)। অতএব, ফলাফল 50। আসুন আবার আমাদের পুরানো বন্ধু 耰কে উদাহরণ হিসাবে নেওয়া যাক, এবং এটিকে কিছু সংখ্যায় যোগ করার চেষ্টা করুন।

public static void main(String[] args) {

   char c = '耰';
   int x = 200;

   System.out.println(c + x);
}
কনসোল আউটপুট: 33016 আমরা ইতিমধ্যেই আবিষ্কার করেছি যে 耰 32816 এর সাথে মিলে যায়। এবং যখন আমরা এই সংখ্যাটি এবং 200 যোগ করি, তখন আমরা আমাদের ফলাফল পাই: 33016। :) আপনি দেখতে পাচ্ছেন, এখানে অ্যালগরিদমটি বেশ সহজ, কিন্তু আপনার এটি ভুলে যাওয়া উচিত নয় .
মন্তব্য
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION