সি তে, শিফট অপারেটরগুলি ( <<
, >>
) পাটিগণিত বা যৌক্তিক?
সি তে, শিফট অপারেটরগুলি ( <<
, >>
) পাটিগণিত বা যৌক্তিক?
উত্তর:
মতে কে & R এর 2nd সংস্করণ ফলাফল বাস্তবায়ন নির্ভর স্বাক্ষরিত মূল্যবোধের অধিকার বদল আনতে হয়।
উইকিপিডিয়া বলছে যে সি / সি ++ 'সাধারণত' স্বাক্ষরিত মানগুলিতে একটি গাণিতিক শিফট প্রয়োগ করে।
মূলত আপনাকে হয় আপনার সংকলকটি পরীক্ষা করতে হবে বা এটির উপর নির্ভর করতে হবে না। আমার এমএস সি ++ কম্পাইলারের জন্য আমার ভিএস ২০০8 সাহায্য বলে যে তাদের সংকলক একটি পাটিগণিত শিফট করে।
বাম দিকে সরানোর সময়, গাণিতিক এবং লজিকাল শিফটে কোনও পার্থক্য নেই is ডান স্থানান্তরিত করার সময়, শিফটের ধরণ স্থানান্তরিত হওয়া মানের ধরণের উপর নির্ভর করে।
(পার্থক্য সম্পর্কে অপরিচিত যারা পাঠকদের পটভূমি হিসাবে, একটি "লজিকাল" ডান শিফট 1 বিট দিয়ে সমস্ত বিটকে ডানে স্থানান্তরিত করে এবং বামদিকের বিটটিতে একটি 0 দিয়ে পূরণ করে একটি "গাণিতিক" শিফটটি মূল মানটি বামদিকের বিটটিতে ছেড়ে যায় Negativeণাত্মক সংখ্যার সাথে কাজ করার সময় পার্থক্যটি গুরুত্বপূর্ণ হয়ে ওঠে))
স্বাক্ষরবিহীন মানটি স্থানান্তর করার সময়, >> সি এর অপারেটরটি একটি লজিকাল শিফট। স্বাক্ষরিত মানটি স্থানান্তরিত করার সময় >> অপারেটর হ'ল গাণিতিক শিফট।
উদাহরণস্বরূপ, একটি 32 বিট মেশিন ধরে:
signed int x1 = 5;
assert((x1 >> 1) == 2);
signed int x2 = -5;
assert((x2 >> 1) == -3);
unsigned int x3 = (unsigned int)-5;
assert((x3 >> 1) == 0x7FFFFFFD);
শিফট অপারেটরের যথাক্রমে বাম এবং ডান ক্রিয়াকলাপ বিবেচনা করুন i
এবং n
হবেন; i
পূর্ণসংখ্যার প্রচারের পরে, প্রকারের T
। অনুমান n
করা হচ্ছে [0, sizeof(i) * CHAR_BIT)
- অন্যথায় সংজ্ঞায়িত - আমরা এই কেসগুলি করেছি:
| Direction | Type | Value (i) | Result |
| ---------- | -------- | --------- | ------------------------ |
| Right (>>) | unsigned | ≥ 0 | −∞ ← (i ÷ 2ⁿ) |
| Right | signed | ≥ 0 | −∞ ← (i ÷ 2ⁿ) |
| Right | signed | < 0 | Implementation-defined† |
| Left (<<) | unsigned | ≥ 0 | (i * 2ⁿ) % (T_MAX + 1) |
| Left | signed | ≥ 0 | (i * 2ⁿ) ‡ |
| Left | signed | < 0 | Undefined |
Comp বেশিরভাগ সংকলকগণ এটি গাণিতিক শিফট হিসাবে প্রয়োগ করেন
value যদি মান ফলাফলের টির উপর দিয়ে প্রবাহিত হয় তবে নির্ধারিত নয়; প্রচারিত প্রকার i
প্রথমত, গাণিতিক দৃষ্টিকোণ থেকে যৌক্তিক এবং গাণিতিক পরিবর্তনের মধ্যে পার্থক্য, ডেটা টাইপের আকার সম্পর্কে চিন্তা না করে। লজিকাল শিফট সর্বদা ফেলে দেওয়া বিটগুলি জিরো দিয়ে পূরণ করে যখন গাণিতিক শিফট এটি কেবল বাম শিফটের জন্য জিরো দিয়ে পূরণ করে, তবে ডান শিফটের জন্য এটি এমএসবি অনুলিপি করে যার ফলে অপারেন্ডের চিহ্নটি সংরক্ষণ করে ( দু'জনের পরিপূরক ধরে ধরে) নেতিবাচক মানগুলির জন্য এনকোডিং )।
অন্য কথায়, যৌক্তিক শিফট স্থানান্তরিত অপরেন্ডকে কেবল বিটের স্রোত হিসাবে দেখায় এবং ফলস্বরূপ মানটির চিহ্ন নিয়ে বিরক্ত না করে এগুলিকে সরিয়ে দেয়। পাটিগণিত শিফট এটিকে (স্বাক্ষরিত) নম্বর হিসাবে দেখায় এবং শিফট তৈরি হওয়ার সাথে সাথে চিহ্নটি সংরক্ষণ করে।
N দ্বারা এক্স সংখ্যার বামে গাণিতিক শিফটটি 2 এন দ্বারা গুণমানের সমান এবং এইভাবে যৌক্তিক বাম শিফটের সমতুল্য; লজিকাল শিফট একই ফলাফল দেয় যেহেতু এমএসবি যেভাবেই শেষের দিকে পড়ে এবং সংরক্ষণের মতো কিছুই নেই।
X দ্বারা n দ্বারা সংখ্যার একটি ডান পাটিগণিত শিফট কেবলমাত্র X দ্বারা 2 n এর পূর্ণসংখ্যা বিভাগের সমান যদি এক্স অ-নেতিবাচক হয়! পূর্ণসংখ্যা বিভাগটি গাণিতিক বিভাগ এবং 0 ( ট্রাঙ্ক ) এর দিকে বৃত্ত ছাড়া কিছুই নয় ।
নেতিবাচক সংখ্যার জন্য, দু'জনের পরিপূরক এনকোডিং দ্বারা প্রতিনিধিত্ব করা, ডান n বিট দ্বারা ডান স্থানান্তরিত করার গাণিতিকভাবে এটি 2 এন দ্বারা বিভক্ত করা এবং −∞ ( তল ) এর দিকে বৃত্তাকার প্রভাব রয়েছে ; এইভাবে ডান স্থানান্তর অ-নেতিবাচক এবং নেতিবাচক মানগুলির জন্য পৃথক।
এক্স ≥ 0, এক্স >> এন = এক্স / 2 এন = ট্রাঙ্ক (এক্স ÷ 2 এন) এর জন্য ) এর জন্য
এক্স <0, এক্স >> এন = ফ্লোর (এক্স ÷ 2 এন ) এর জন্য
÷
গাণিতিক বিভাগ যেখানে , /
পূর্ণসংখ্যা বিভাগ। আসুন একটি উদাহরণ তাকান:
37) 10 = 100101) 2
37 ÷ 2 = 18.5
37/2 = 18 (0 0-এর দিকে 18.5 বৃত্তাকার) = 10010) 2 [গাণিতিক ডান শিফ্টের ফলাফল]
-37) 10 = 11011011) 2 (দু'জনের পরিপূরক, 8-বিটের উপস্থাপনা বিবেচনা করে)
-37। 2 = -18.5
-37 / 2 = -18 (0 0-র দিকে 18.5 বৃত্তাকার) = 11101110) 2 [গাণিতিক ডান শিফ্টের ফলাফল নয়]
-37 >> 1 = -19 (18.5 বৃত্তাকার দিকে) = 11101101) 2 [পাটিগণিত ডান স্থানান্তরিত ফলাফল]
গাই স্টিল যেমন উল্লেখ করেছেন , এই তাত্পর্যটি একাধিক সংকলকতে বাগগুলি নিয়েছে । এখানে অ-নেতিবাচক (গণিত) স্বাক্ষরযুক্ত এবং স্বাক্ষরিত অ-নেতিবাচক মানগুলিতে (সি) ম্যাপ করা যেতে পারে; উভয়ই একইরকম আচরণ করা হয় এবং তাদের ডান-শিফটিংটি পূর্ণসংখ্যা বিভাগ দ্বারা সম্পন্ন হয়।
সুতরাং যৌক্তিক এবং পাটিগণিতগুলি বাম-স্থানান্তর এবং ডান স্থানান্তরের ক্ষেত্রে অ-নেতিবাচক মানের জন্য সমতুল্য; এটি ঠিক যে নেতিবাচক মানগুলি পৃথক করে তা সরানো।
স্ট্যান্ডার্ড সি 99 §6.5.7 :
অপারেন্ডগুলির প্রত্যেকের পূর্ণসংখ্যার ধরণ থাকবে।
পূর্ণসংখ্যা প্রচারগুলি প্রতিটি অপারেন্ডে সম্পাদিত হয়। ফলাফলের ধরণটি হ'ল প্রচারিত বাম অপারেন্ড। যদি ডান অপরেন্ডের মান negativeণাত্মক হয় বা প্রচারিত বাম অপারেন্ডের প্রস্থের চেয়ে বড় বা সমান হয়, তবে আচরণটি অনির্ধারিত।
short E1 = 1, E2 = 3;
int R = E1 << E2;
উপরের স্নিপেটে, উভয় অপারেশন হয়ে যায় int
(পূর্ণসংখ্যার প্রচারের কারণে); যদি E2
নেতিবাচক হয় বা E2 ≥ sizeof(int) * CHAR_BIT
তারপরে অপারেশনটি অপরিজ্ঞাত হয়। এটি কারণ উপলব্ধ বিটগুলির চেয়ে বেশি স্থানান্তরিত হওয়া অবশ্যই ওভারফ্লোতে চলেছে। ছিল R
ঘোষণা করা যেমন short
, int
শিফট অপারেশন ফলাফলের পরোক্ষভাবে রূপান্তরিত করা হবে short
; সংকীর্ণ রূপান্তর, যা গন্তব্যের ধরণের মানটি উপস্থাপনযোগ্য না হলে বাস্তবায়ন-সংজ্ঞায়িত আচরণের দিকে পরিচালিত করে।
E1 এর ফলাফল << E2 হল E1 বাম-স্থানান্তরিত E2 বিট অবস্থান; শূন্য বিট জিরো দিয়ে ভরা হয়। যদি E1 এর স্বাক্ষরবিহীন প্রকারের থাকে তবে ফলাফলটির মান E1 × 2 E2 হয় , ফলাফলের ধরণটিতে উপস্থাপনযোগ্য সর্বোচ্চ মানের তুলনায় মডুলোকে আরও একটি হ্রাস করে। যদি E1 এর একটি স্বাক্ষরিত ধরণের এবং অ-নেতিবাচক মান থাকে এবং ফলাফল প্রকারের E1 × 2 E2 উপস্থাপনযোগ্য হয়, তবে এটি ফলাফল মান; অন্যথায়, আচরণটি সংজ্ঞায়িত।
বাম শিফট উভয়ের জন্য সমান হওয়ায় শূন্য বিটগুলি কেবল জিরো দিয়ে পূর্ণ হয়। এরপরে বলা হয়েছে যে স্বাক্ষরযুক্ত ও স্বাক্ষরিত উভয় প্রকারের জন্য এটি একটি গাণিতিক শিফট। আমি এটিকে গাণিতিক শিফট হিসাবে ব্যাখ্যা করছি যেহেতু লজিকাল শিফটগুলি বিট দ্বারা উপস্থাপিত মানটি নিয়ে মাথা ঘামায় না, এটি কেবল এটি বিটের স্রোত হিসাবে দেখায়; কিন্তু মানটি বিটের ক্ষেত্রে নয়, তবে E1 এর পণ্যটি 2 E2 দিয়ে প্রাপ্ত মানের ক্ষেত্রে এটি সংজ্ঞায়িত করে ।
এখানে সতর্কতাই হ'ল স্বাক্ষরিত ধরণের জন্য মানটি অ-নেতিবাচক হওয়া উচিত এবং ফলস্বরূপ মানটি ফলাফলের ক্ষেত্রে উপস্থাপনযোগ্য হওয়া উচিত। অন্যথায় অপারেশন অপরিজ্ঞাত। ফলাফলের ধরণটি E1 এর ধরণের হবে যা অবিচ্ছেদ্য প্রচারের পরে প্রয়োগ করা হবে এবং গন্তব্য নয় (ভেরিয়েবল যা ফলাফলটি ধরে রাখবে) প্রকার। ফলস্বরূপ মানটি গন্তব্যের ধরণে স্পষ্টত রূপান্তরিত হয়; যদি এটি সেই ধরণের উপস্থাপনযোগ্য না হয় তবে রূপান্তরটি বাস্তবায়ন-সংজ্ঞায়িত (C99 .6.3.1.3 / 3)।
E1 যদি একটি নেতিবাচক মান সহ একটি স্বাক্ষরিত ধরণ হয় তবে বাম স্থানান্তরিত আচরণটি অপরিজ্ঞাত। এটি অনির্ধারিত আচরণের জন্য একটি সহজ রুট যা সহজেই উপেক্ষা করা যেতে পারে।
E1 >> E2 এর ফলাফল হ'ল E1 ডান স্থানান্তরিত E2 বিট অবস্থান। যদি E1 এর স্বাক্ষরবিহীন প্রকার থাকে বা E1 এর একটি স্বাক্ষরিত প্রকার এবং একটি নেতিবাচক রয়েছে তবে ফলাফলের মান E1 / 2 E2 এর ভাগফলের অবিচ্ছেদ্য অংশ । যদি E1 এর একটি স্বাক্ষরিত ধরণ এবং negativeণাত্মক মান থাকে তবে ফলাফল মান বাস্তবায়ন-সংজ্ঞায়িত হয়।
স্বাক্ষরযুক্ত এবং স্বাক্ষরিত অ-নেতিবাচক মানগুলির জন্য ডান শিফটটি বেশ সোজা এগিয়ে রয়েছে; শূন্য বিটগুলি শূন্যে ভরা হয়। স্বাক্ষরিত নেতিবাচক মানগুলির জন্য ডান শিফটিংয়ের ফলাফলটি বাস্তবায়ন-সংজ্ঞায়িত হয়। এটি বলেছে যে, সিসি বিট সংরক্ষণ করে জিসিসি এবং ভিজ্যুয়াল সি ++ এর মতো বেশিরভাগ বাস্তবায়নগুলি পাটিগণিতের স্থানান্তর হিসাবে ডান-শিফটিং প্রয়োগ করে।
জাভা থেকে পৃথক, যা >>>
সাধারণ থেকে পৃথকভাবে লজিকাল শিফটিংয়ের জন্য একটি বিশেষ অপারেটর >>
এবং <<
সি এবং সি ++ এর কিছু অঞ্চলে অপরিজ্ঞাত এবং বাস্তবায়ন-সংজ্ঞায়িত কেবল পাটিগণিতের স্থানান্তর রয়েছে। আমি তাদের গাণিতিক হিসাবে বিবেচনা করার কারণটি হ'ল পরিবর্তিত ক্রিয়াকলাপকে বিটের স্রোত হিসাবে বিবেচনা করার পরিবর্তে গণিতের ক্রিয়াকলাপের কারণে operation এটি সম্ভবত এই কারণে যে সমস্ত ক্ষেত্রগুলিকে কেবল যৌক্তিক স্থানান্তর হিসাবে সংজ্ঞায়িত করার পরিবর্তে এই অঞ্চলগুলিকে আন / বাস্তবায়ন-সংজ্ঞায়িত ছেড়ে দেয়।
-Inf
নেতিবাচক এবং ধনাত্মক উভয় সংখ্যার জন্য ডান শিফট রাউন্ড । একটি ধনাত্মক সংখ্যা 0 দিকে রাউন্ডইং প্রতি rounding তার একটি ব্যক্তিগত ক্ষেত্রে দেখা যায় -Inf
। সংক্ষিপ্তকরণ করার সময়, আপনি সর্বদা ইতিবাচক ওজনযুক্ত মান বাদ দেন, তাই আপনি অন্যথায় সুনির্দিষ্ট ফলাফল থেকে বিয়োগ করেন।
আপনি যে ধরণের শিফট পান সেটির ক্ষেত্রে, গুরুত্বপূর্ণ জিনিসটি হ'ল আপনি যে মানটি স্থানান্তরিত করছেন তা। বাগের একটি ক্লাসিক উত্স হ'ল আপনি যখন আক্ষরিক স্থানান্তরিত করুন, বলুন, বিটগুলি বন্ধ করে দিন। উদাহরণস্বরূপ, আপনি যদি স্বাক্ষর વિના স্বাক্ষরিত পূর্ণসংখ্যার বাম-বিটটি বাদ দিতে চান তবে আপনি এটি আপনার মুখোশ হিসাবে চেষ্টা করতে পারেন:
~0 >> 1
দুর্ভাগ্যক্রমে, এটি আপনাকে সমস্যায় ফেলবে কারণ মুখোশটির সমস্ত বিট সেট হয়ে যাবে কারণ মানটি স্থানান্তরিত হচ্ছে (~ 0) স্বাক্ষরিত হয়েছে, এভাবে পাটিগণিতের শিফ্টটি সম্পাদন করা হয়। পরিবর্তে, আপনি মানটিকে স্বাক্ষরবিহীন হিসাবে পরিষ্কারভাবে ঘোষণা করে অর্থাত্ এই জাতীয় কিছু করে একটি যৌক্তিক শিফটটি জোর করতে চাইবেন:
~0U >> 1;
লজিকাল ডান শিফট এবং সি-তে একটি ইন্টের অঙ্কগুলি গণিতের ডান শিফ্টের গ্যারান্টি দেওয়ার জন্য এখানে ফাংশন রয়েছে:
int logicalRightShift(int x, int n) {
return (unsigned)x >> n;
}
int arithmeticRightShift(int x, int n) {
if (x < 0 && n > 0)
return x >> n | ~(~0U >> n);
else
return x >> n;
}
আপনি যখন করেন - বাম শিফটটি 1 দিয়ে আপনি 2 দিয়ে গুণ করেন - ডান শিফটটি 1 দিয়ে আপনি 2 দ্বারা ভাগ করেন
x = 5
x >> 1
x = 2 ( x=5/2)
x = 5
x << 1
x = 10 (x=5*2)
ওয়েল, আমি এটি উইকিপিডিয়ায় দেখেছি এবং তাদের এই কথাটি আছে:
সি, তবে কেবল একটি ডান শিফট অপারেটর রয়েছে, >>। অনেক সি সংকলক কোন ধরণের শিফটটি কোন ধরণের পূর্ণসংখ্যা স্থানান্তরিত হচ্ছে তার উপর নির্ভর করে কোন ডান শিফট সম্পাদন করতে চান তা বেছে নেয়; প্রায়শই স্বাক্ষরিত পূর্ণসংখ্যার গাণিতিক শিফট ব্যবহার করে স্থানান্তরিত করা হয় এবং স্বাক্ষরযুক্ত পূর্ণ সংখ্যাগুলি লজিকাল শিফ্ট ব্যবহার করে স্থানান্তরিত হয়।
এটি আপনার সংকলকের উপর নির্ভর করে বলে মনে হচ্ছে। এছাড়াও সেই নিবন্ধে, নোট করুন যে বাম শিফটটি গাণিতিক এবং যৌক্তিক জন্য একই। আমি সীমান্ত কেসে কিছু স্বাক্ষরিত এবং স্বাক্ষরবিহীন সংখ্যাসমূহের সাথে একটি সহজ পরীক্ষা করার পরামর্শ দেব (অবশ্যই উচ্চ বিট সেট) এবং ফলাফলটি আপনার সংকলকটিতে কী আছে তা দেখুন। আমি এটির একে একে বা অন্যটি হওয়ার উপর নির্ভর করে এড়িয়ে চলারও পরামর্শ দেব কারণ এটির সি এর কোনও মান নেই, কমপক্ষে যদি নির্ভরযোগ্য এবং এ জাতীয় নির্ভরতা এড়ানো সম্ভব হয়।
বাম স্থানান্তর <<
এটি কোনওরকম সহজ এবং আপনি যখনই শিফট অপারেটরটি ব্যবহার করেন এটি সর্বদা সামান্য বুদ্ধিমান অপারেশন হয়, তাই আমরা এটি একটি ডাবল এবং ফ্লোট অপারেশন সহ ব্যবহার করতে পারি না। যখনই আমরা একটি শূন্য শিফট ছেড়ে যাই, এটি সর্বদা সর্বনিম্ন উল্লেখযোগ্য বিটে যুক্ত হয় (LSB
) এ যুক্ত হয়।
তবে ডান শিফটে >>
আমাদের একটি অতিরিক্ত নিয়ম অনুসরণ করতে হবে এবং সেই নিয়মটিকে "সাইন বিট কপি" বলা হয়। "সাইন বিট অনুলিপি" এর অর্থ হ'ল যদি সর্বাধিক তাৎপর্যপূর্ণ বিট ( MSB
) সেট করা থাকে তবে ডান শিফ্টের পরে আবার MSB
সেট করা হবে যদি এটি পুনরায় সেট করা হয় তবে এটি আবার পুনরায় সেট করা হয়, এর অর্থ যদি পূর্ববর্তী মানটি শূন্য হয় তবে আবার স্থানান্তরিত হওয়ার পরে, বিট শূন্য যদি পূর্বের বিটটি এক হয় তবে শিফটের পরে এটি আবার একটি হয়। এই নিয়মটি বাম শিফটের জন্য প্রযোজ্য নয়।
ডান শিফ্টের সর্বাধিক গুরুত্বপূর্ণ উদাহরণ যদি আপনি কোনও নেতিবাচক সংখ্যাকে ডান শিফটে স্থানান্তর করেন তবে কিছুটা স্থানান্তরিত হওয়ার পরে অবশেষে শূন্যে পৌঁছে যায় এবং তারপরে যদি এই -1 শিফট হয় তবে যে কোনও সংখ্যার মান একই থাকবে। দয়া করে চেক করুন।
জিসিসি করে
জন্য -> পাটিগণিত শিফট
+ Ve -> লজিকাল শিফ্টের জন্য
অনেকের মতে গ কম্পাইলার:
<<
একটি গাণিতিক বাম শিফট বা বিটওয়াস বাম শিফট is>>
একটি গাণিতিক ডান শিফটার বিটওয়াইস রাইট শিফ্ট।>>
গাণিতিক নাকি বিটওয়াইজ (যৌক্তিক)?" আপনি উত্তর দিয়েছেন " >>
গাণিতিক বা বিটওয়াইজ"। যে প্রশ্নের উত্তর দেয় না।
<<
এবং >>
অপারেটরগুলি যৌক্তিক নয়, গাণিতিক নয়