আমি একটি ফাংশন সংজ্ঞায়িত করতে চাই যা unsigned int
আর্গুমেন্ট হিসাবে গ্রহণ করে এবং যুক্তির জন্য একটি int
সম্মিলিত Modulo UINT_MAX + 1 প্রদান করে।
প্রথম চেষ্টাটি দেখতে এরকম হতে পারে:
int unsigned_to_signed(unsigned n)
{
return static_cast<int>(n);
}
তবে যে কোনও ভাষার আইনজীবী জানেন, INT_MAX এর চেয়ে বড় মানের জন্য স্বাক্ষরযুক্ত থেকে স্বাক্ষর করা প্রয়োগ-সংজ্ঞায়িত।
আমি এটিকে বাস্তবায়িত করতে চাই যে (ক) এটি কেবল অনুমানের দ্বারা বাধ্যতামূলক আচরণের উপর নির্ভর করে; এবং (খ) এটি যে কোনও আধুনিক মেশিনে কোনও সংযোজন এবং সংকলককে অনুকূলকরণের মধ্যে সংকলন করে।
উদ্ভট মেশিনগুলির জন্য ... স্বাক্ষরযুক্ত স্বাক্ষরের জন্য যদি স্বাক্ষরযুক্ত কোনও সংঘের মডেল UINT_MAX + 1 না থাকে তবে ধরা যাক আমি একটি ব্যতিক্রম ছুঁড়ে দিতে চাই। যদি একের বেশি থাকে (তবে আমি নিশ্চিত যে এটি সম্ভব) তবে আসুন আমরা বলি যে আমি সবচেয়ে বড় চাই।
ঠিক আছে, দ্বিতীয় প্রচেষ্টা:
int unsigned_to_signed(unsigned n)
{
int int_n = static_cast<int>(n);
if (n == static_cast<unsigned>(int_n))
return int_n;
// else do something long and complicated
}
আমি যখন সাধারণ দ্বিগুণ-পরিপূরক সিস্টেমে না থাকি তখন দক্ষতার বিষয়ে খুব বেশি যত্ন নিই না, যেহেতু আমার নম্র মতামতটি এর সম্ভাবনা কম। এবং যদি আমার কোডটি 2050 এর সর্বজনীন চিহ্ন-মাত্রার সিস্টেমে একটি বাধা হয়ে দাঁড়ায়, তবে আমি বাজি ধরছি যে কেউ তা খুঁজে বের করতে পারে এবং এটি তখনই অনুকূলিত করতে পারে।
এখন, এই দ্বিতীয় প্রচেষ্টাটি আমি যা চাই তার কাছাকাছি। যদিও কাস্টে int
কিছু ইনপুটগুলির জন্য বাস্তবায়ন-সংজ্ঞায়িত করা হয়েছে, তবে কাস্ট করতে unsigned
ব্যাকটিকে মান মডিউল UINT_MAX + 1 সংরক্ষণের মান দ্বারা গ্যারান্টিযুক্ত। সুতরাং শর্তসাপেক্ষে আমি যা চাই ঠিক তা যাচাই করে না এবং এটি আমার মুখোমুখি হওয়ার মতো কোনও সিস্টেমে সংকলিত হবে।
তবে ... আমি int
এটি এখনও বাস্তবায়ন-সংজ্ঞায়িত আচরণের জন্য প্রার্থনা করব কিনা তা আগে পরীক্ষা না করেই কাস্ট করছি । 2050 সালে কিছু অনুমানমূলক সিস্টেমে এটি কে-জানে-কী করতে পারে। সুতরাং আসুন আমি এটি এড়াতে চাই বলি।
প্রশ্ন: আমার "তৃতীয় প্রচেষ্টা" দেখতে কেমন হবে?
পুনরুদ্ধার করতে, আমি চাই:
- স্বাক্ষরবিহীন অন্তর্ভুক্ত থেকে স্বাক্ষর করা ইন কাস্ট করুন
- UINT_MAX + 1 মানটি সংরক্ষণ করুন
- কেবল মান-বাধ্যতামূলক আচরণটি চালান
- সংযোজকটি অনুকূলকরণের সাথে একটি আদর্শ দুটি দ্বিগুণ-পরিপূরক মেশিনে একটি অন-সংকলন করুন
[হালনাগাদ]
এটি কেন তুচ্ছ প্রশ্ন নয় তা দেখানোর জন্য আমি একটি উদাহরণ দিই।
নিম্নলিখিত বৈশিষ্ট্য সহ একটি অনুমান সি ++ বাস্তবায়ন বিবেচনা করুন:
sizeof(int)
সমান 4sizeof(unsigned)
সমান 4INT_MAX
সমান 32767INT_MIN
সমান -2 32 + 32768UINT_MAX
সমান 2 32 - 1- পাটিগণিত উপর
int
মডিউল 2 32 (পরিসীমা মধ্যেINT_MIN
দিয়েINT_MAX
) std::numeric_limits<int>::is_modulo
সত্য- স্বাক্ষরযুক্ত স্বাক্ষর না
n
করা কাস্ট করা 0 <= n <= 32767 এর মান সংরক্ষণ করে এবং অন্যথায় শূন্য দেয়
এই int
হাইপোটিকাল বাস্তবায়নের ক্ষেত্রে প্রতিটি unsigned
মানের জন্য ঠিক এক মান সম্মত (Mod UINT_MAX + 1) থাকে । সুতরাং আমার প্রশ্নটি সঠিকভাবে সংজ্ঞায়িত হবে।
আমি দাবি করি যে এই হাইপোথটিক্যাল সি ++ বাস্তবায়ন সি ++ 98, সি ++ 03 এবং সি ++ 11 টি নির্দিষ্টকরণের সাথে পুরোপুরি মেনে চলে। আমি স্বীকার করি আমি সেগুলির প্রত্যেকটি শব্দ মুখস্থ করতে পারি নি ... তবে আমি বিশ্বাস করি আমি প্রাসঙ্গিক বিভাগগুলি মনোযোগ সহকারে পড়েছি। সুতরাং আপনি যদি আমার উত্তরটি গ্রহণ করতে চান তবে আপনাকে অবশ্যই (ক) এমন অনুমানের কথা উল্লেখ করতে হবে যা এই অনুমান বাস্তবায়নকে বাতিল করে দেয় বা (খ) এটিকে সঠিকভাবে পরিচালনা করবে।
প্রকৃতপক্ষে, একটি সঠিক উত্তর অবশ্যই মান দ্বারা অনুমোদিত প্রতিটি অনুমানমূলক বাস্তবায়ন পরিচালনা করতে হবে । সংজ্ঞা অনুসারে এটিই "কেবলমাত্র মান-বাধ্যতামূলক আচরণের আহ্বান করুন" এর অর্থ।
ঘটনাক্রমে, নোট যে std::numeric_limits<int>::is_modulo
একাধিক কারণে এখানে সম্পূর্ণ বেহুদা। একটি জিনিসের জন্য, এটি true
স্বাক্ষরযুক্ত-স্বাক্ষরিত কাস্টগুলি বৃহত্তর স্বাক্ষরিত মানগুলির জন্য কাজ না করলেও তা হতে পারে । অন্যটির জন্য, এটি কারও true
পরিপূরক বা সাইন-প্রস্থের সিস্টেমেও হতে পারে, যদি গাণিতিকটি কেবল পুরো পূর্ণসংখ্যার পরিসীমাটি মডিউল করে। ইত্যাদি। আপনার উত্তর যদি নির্ভর করে তবে is_modulo
এটি ভুল।
[আপডেট 2]
এইচডিডি এর উত্তর আমাকে কিছু শিখিয়েছে: আমার পূর্ণসংখ্যার জন্য সি ++ বাস্তবায়ন আধুনিক সি দ্বারা অনুমোদিত নয় সি 99 এবং সি 11 মান স্বাক্ষরিত পূর্ণসংখ্যার উপস্থাপনা সম্পর্কে খুব নির্দিষ্ট; প্রকৃতপক্ষে, তারা কেবল দ্বিগুণ-পরিপূরক, পরিপূরক, এবং সাইন-প্রস্থের (বিভাগ 6.2.6.2 অনুচ্ছেদ (2);) অনুমতি দেয়।
তবে সি ++ সি নয়, যেমনটি দেখা যাচ্ছে, এই ঘটনাটি আমার প্রশ্নের একেবারে কেন্দ্রবিন্দুতে lies
মূল সি ++ 98 স্ট্যান্ডার্ডটি অনেক পুরানো সি 98 এর উপর ভিত্তি করে তৈরি হয়েছিল, যা বলে (বিভাগ 3.1.2.5):
স্বাক্ষরিত প্রতিটি পূর্ণসংখ্যার প্রকারের জন্য, স্বাক্ষরযুক্ত স্বাক্ষরযুক্ত পূর্ণসংখ্যার টাইপ (স্বাক্ষরবিহীন কীওয়ার্ড দিয়ে মনোনীত) থাকে যা সমান পরিমাণ স্টোরেজ (সাইন ইন তথ্য সহ) ব্যবহার করে এবং একই রকম প্রান্তিককরণের প্রয়োজনীয়তা রয়েছে। একটি স্বাক্ষরিত পূর্ণসংখ্যার ধরণের অব্যবহৃত মানগুলির সীমাটি স্বাক্ষরযুক্ত স্বাক্ষরিত পূর্ণসংখ্যা টাইপের একটি সাবরেঞ্জ এবং প্রতিটি ধরণের একই মানের প্রতিনিধিত্ব একই।
সি 89 কেবলমাত্র একটি সাইন বিট থাকার বা কেবল দ্বি-পরিপূরক / বেশী-পরিপূরক / সাইন-প্রস্থের অনুমতি দেওয়ার বিষয়ে কিছুই বলে না।
সি ++ 98 স্ট্যান্ডার্ড প্রায় ভাষাটি এই ভাষাটি গ্রহণ করেছে (বিভাগ 3.9.1 অনুচ্ছেদ (3)):
স্বাক্ষরিত প্রতিটি পূর্ণসংখ্যার ধরণের জন্য, একটি স্বাক্ষরযুক্ত (তবে ভিন্ন) স্বাক্ষরযুক্ত পূর্ণসংখ্যার টাইপ রয়েছে : "
unsigned char
", "unsigned short int
", "unsigned int
" এবং "unsigned long int
", যার প্রত্যেকটিতে একই পরিমাণ সঞ্চয়স্থান রয়েছে এবং একই প্রান্তিককরণের প্রয়োজনীয়তা রয়েছে (3.9) ) সম্পর্কিত স্বাক্ষরিত পূর্ণসংখ্যা টাইপ হিসাবে; এটি হ'ল প্রতিটি স্বাক্ষরিত পূর্ণসংখ্যার টাইপটির সাথে সম্পর্কিত স্বাক্ষরযুক্ত পূর্ণসংখ্যা টাইপের মতো একই অবজেক্টের উপস্থাপনা থাকে । একটি স্বাক্ষরিত পূর্ণসংখ্যার ধরণের অবৈধ মানগুলির সীমাটি স্বাক্ষরিত স্বাক্ষরযুক্ত পূর্ণসংখ্যা টাইপের একটি সাবরেঞ্জ এবং প্রতিটি স্বাক্ষরিত / স্বাক্ষরবিহীন প্রকারের মান প্রতিনিধিত্ব একই হবে।
সি ++ 03 স্ট্যান্ডার্ড মূলত অভিন্ন ভাষা ব্যবহার করে, যেমন সি ++ 11 করে।
যতটা আমি বলতে পারি কোনও মানক সি ++ স্পেস তার স্বাক্ষরিত পূর্ণসংখ্যার উপস্থাপনাটিকে কোনও সি স্পিকে সীমাবদ্ধ করে না। এবং একক চিহ্ন বিট বা ধরণের কিছু বাধ্যতামূলক করার কিছুই নেই। কেবলমাত্র এটিই বলে যে অ-নেতিবাচক স্বাক্ষরিত পূর্ণসংখ্যাগুলি অবশ্যই স্বাক্ষরবিহীন স্বাক্ষরযুক্ত সাব্রিজ হতে হবে।
সুতরাং, আমি আবার দাবি করি যে INT_MIN = -2 32 +32768 সহ INT_MAX = 32767 অনুমোদিত। যদি আপনার উত্তরটি অন্যথায় ধরে নেওয়া হয়, তবে আপনি ভুল সি প্রমাণিত কোনও সি ++ না দিলে এটি ভুল।