(-2147483648> 0) সি ++ এ সত্য ফিরে আসে?


241

-2147483648 হল 32 বিটের সাহায্যে পূর্ণসংখ্যার ধরণের ছোটতম পূর্ণসংখ্যা, তবে মনে হয় if(...)বাক্যটিতে এটি উপচে পড়বে :

if (-2147483648 > 0)
    std::cout << "true";
else
    std::cout << "false";

এটি trueআমার পরীক্ষায় মুদ্রণ করবে । তবে, আমরা যদি পূর্ণসংখ্যার জন্য -2147483648 কাস্ট করি তবে ফলাফলটি ভিন্ন হবে:

if (int(-2147483648) > 0)
    std::cout << "true";
else
    std::cout << "false";

এটি মুদ্রণ করবে false

আমি বিভ্রান্ত কেউ কি এই সম্পর্কে একটি ব্যাখ্যা দিতে পারেন?


02-05-2012 আপডেট করুন:

আপনার মন্তব্যের জন্য ধন্যবাদ, আমার সংকলকটিতে, int এর আকার 4 বাইট। আমি কিছু সাধারণ পরীক্ষার জন্য ভিসি ব্যবহার করছি। আমি আমার প্রশ্নের বিবরণ পরিবর্তন করেছি।

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


48
"আমরা সবাই জানি যে -2147483648 হল পূর্ণসংখ্যার ক্ষুদ্রতম সংখ্যা" এটি পূর্ণসংখ্যার আকারের উপর নির্ভর করে।
orlp

14
"আমরা সকলেই জানি যে -2147483648 হল পূর্ণসংখ্যার সংক্ষিপ্ত সংখ্যা" - আমি ভেবেছিলাম যে কোনও ছোট সংখ্যার পূর্ণসংখ্যার উপস্থিতি নেই, যেহেতু তাদের মধ্যে অনেকগুলিই রয়েছে ... যাই হোক না কেন।

4 বাইট পূর্ণসংখ্যার সঙ্গে @Inisheer আপনি একটি থাকতে পারে INT_MINএর -9223372036854775808, যদিCHAR_BIT 16 এমনকি সাথে আছেন CHAR_BIT == 8এবং sizeof(int== 4) `আপনি পেতে পারেন -9223372036854775807কারণ সি 2-পরিপূর্ণ সংখ্যা প্রয়োজন হয় না।
12431234123412341234123

উত্তর:


391

-2147483648একটি "সংখ্যা" নয়। সি ++ ভাষা নেতিবাচক আক্ষরিক মানকে সমর্থন করে না।

-2147483648 আসলে একটি অভিব্যক্তি: একটি ইতিবাচক আক্ষরিক মান 2147483648- এর সামনে আনরি অপারেটরের সাথে । আপনার প্ল্যাটফর্মের পরিসীমাটির 2147483648ইতিবাচক দিকের জন্য মানটি দৃশ্যত খুব বড় int। যদি টাইপ long intআপনার প্ল্যাটফর্মে বৃহত্তর পরিসর ছিল, কম্পাইলার স্বয়ংক্রিয়ভাবে সেটি অনুমান করতে হবে 2147483648হয়েছে long intপ্রকার। (সি ++ ১১-এ সংকলকটিও long long intটাইপ বিবেচনা করতে হবে)) এটি সংকলকটিকে -2147483648বৃহত্তর প্রকারের ডোমেনে মূল্যায়ন করতে সক্ষম করবে এবং ফলাফলটি নেতিবাচক হবে, যেমনটি প্রত্যাশা করবে।

তবে আপাতদৃষ্টিতে আপনার ক্ষেত্রে পরিসীমা long intহ'ল ব্যাপ্তির সমান intএবং সাধারণভাবে intআপনার প্ল্যাটফর্মের চেয়ে বড় পরিসরের কোনও পূর্ণসংখ্যার প্রকার নেই । এর আনুষ্ঠানিক অর্থ হ'ল ধনাত্মক ধ্রুবকটি 2147483648সমস্ত উপলভ্য স্বাক্ষরিত পূর্ণসংখ্যার ধরণের প্রবাহকে প্রবাহিত করে, যার ফলস্বরূপ আপনার প্রোগ্রামের আচরণটি সংজ্ঞায়িত। (এটি কিছুটা আশ্চর্যের বিষয় যে ডায়াগনস্টিক বার্তার প্রয়োজনের পরিবর্তে ভাষা স্পেসিফিকেশন এই জাতীয় ক্ষেত্রে অনির্ধারিত আচরণের জন্য বেছে নেয় তবে এটি সেভাবেই হয়))

অনুশীলনে, আচরণটি অনির্ধারিত হয়েছে তা বিবেচনায় নিয়ে 2147483648কিছু বাস্তবায়ন-নির্ভর নেতিবাচক মান হিসাবে ব্যাখ্যা করা যেতে পারে যা এটি অবিচ্ছিন্নভাবে -প্রয়োগ করার পরে ইতিবাচক হয়ে ওঠে । বিকল্পভাবে, কিছু বাস্তবায়ন মান উপস্থাপনের জন্য স্বাক্ষরযুক্ত প্রকারগুলি ব্যবহারের চেষ্টা করার সিদ্ধান্ত নিতে পারে (উদাহরণস্বরূপ, C89 / 90 সংকলকগুলিতে ব্যবহারের প্রয়োজন ছিল unsigned long int, তবে সি 99 বা সি ++ তে নয়)। বাস্তবায়নটিকে কিছু করার অনুমতি দেওয়া হয়, যেহেতু আচরণটি যে কোনওভাবেই সংজ্ঞায়িত।

পার্শ্ব নোট হিসাবে, এই কারণেই ধ্রুবকগুলি INT_MINসাধারণত হিসাবে সংজ্ঞায়িত হয়

#define INT_MIN (-2147483647 - 1)

আপাতদৃষ্টিতে আরও সহজবোধ্য পরিবর্তে

#define INT_MIN -2147483648

পরেরটি ইচ্ছাকৃতভাবে কাজ করবে না।


78
এটাও কেন এই কাজ করা হয় হল: #define INT_MIN (-2147483647 - 1)
orlp

5
@ রিচার্ড জে.রোসআইআইআই - ঝাঁকুনির সাহায্যে আপনি সম্ভবত একটি -৪-বিট-টাইপযুক্ত আক্ষরিক পেয়ে যাচ্ছেন, যেহেতু এটি কোনও ক্ষেত্রে ফিট করা খুব বড় ছিল int। ওপির প্রয়োগের ক্ষেত্রে 64৪-বিট প্রকারের নাও থাকতে পারে।
কার্ল নরম

1
@ রিচার্ডজে.রোসআইআইআই: আমি বিশ্বাস করি যে এই আচরণটি বাস্তবায়ন-সংজ্ঞায়িত / অপরিজ্ঞাত।
অলিভার চার্লসওয়ার্থ

3
আমি কখনই ভাবিনি যে একটি "negativeণাত্মক সংখ্যা" এর যেমন পার্স করা হয়নি। আমি কোন কারণ দেখছি না। আমি আশা করি এটি -1.0একটি নেতিবাচক দ্বিগুণ হিসাবে পার্স করা হয়েছে, তাই না?
লীমস

6
@ কিপিসিআরসিআর 4 ভাইরাস: না। আমি আপনার উত্তরে আমার মন্তব্যে যেমন লিখেছি, আধুনিক সি বা সি ++ কেউই এই ক্ষেত্রে স্বাক্ষরযুক্ত প্রকারগুলি ব্যবহারের অনুমতি দেয় না (একটি অসম্পূর্ণ দশমিক ধ্রুবক সহ )। unsigned long intএই প্রসঙ্গে কেবল প্রথম স্ট্যান্ডার্ড সি (C89 / 90) এর অনুমতি দেওয়া হয়েছিল তবে C99 এ এই অনুমতিটি সরানো হয়েছে। সি এবং সি ++ এ অসমাপ্ত অক্ষরগুলিতে স্বাক্ষরযুক্ত ধরণের হওয়া আবশ্যক। আপনি যদি এখানে স্বাক্ষরযুক্ত প্রকারটি দেখতে পান যখন কোনও স্বাক্ষরযুক্ত কোনও কাজ করে, তার অর্থ আপনার সংকলকটি নষ্ট হয়ে গেছে। আপনি যদি স্বাক্ষরযুক্ত প্রকারটি এখানে দেখতে পান যখন কোনও স্বাক্ষরিত প্রকারটি কাজ না করে, তবে এটি কেবল অপরিজ্ঞাত আচরণের একটি নির্দিষ্ট প্রকাশ manifest
এএনটি

43

সংকলক (ভিসি ২০১২) মানটিকে ধরে রাখতে পারে এমন "সর্বনিম্ন" পূর্ণসংখ্যায় প্রচার করে। প্রথম ক্ষেত্রে, signed int(এবং long int) (আগে চিহ্ন প্রয়োগ করা হয়) করতে পারে না, কিন্তু unsigned intযা করতে পারেন: 2147483648হয়েছেunsigned int ???? টাইপ করুন। দ্বিতীয় আপনি জোর intথেকে unsigned

const bool i= (-2147483648 > 0) ;  //   --> true

সতর্কতা C4146: অ্যানারি মাইনাস অপারেটর স্বাক্ষরযুক্ত প্রকারে প্রয়োগ হয়েছে , ফলাফলটি এখনও স্বাক্ষরযুক্ত

এখানে সম্পর্কিত "কৌতূহল" রয়েছে:

const bool b= (-2147483647      > 0) ; //  false
const bool i= (-2147483648      > 0) ; //  true : result still unsigned
const bool c= ( INT_MIN-1       > 0) ; //  true :'-' int constant overflow
const bool f= ( 2147483647      > 0) ; //  true
const bool g= ( 2147483648      > 0) ; //  true
const bool d= ( INT_MAX+1       > 0) ; //  false:'+' int constant overflow
const bool j= ( int(-2147483648)> 0) ; //  false : 
const bool h= ( int(2147483648) > 0) ; //  false
const bool m= (-2147483648L     > 0) ; //  true 
const bool o= (-2147483648LL    > 0) ; //  false

সি ++ 11 মান :

২.১৪.২ পূর্ণসংখ্যা অক্ষর [লেক্স.আইকন]

...

একটি পূর্ণসংখ্যা আক্ষরিক হ'ল ডিজিটের ক্রম যা এর কোনও পিরিয়ড বা এক্সপোনেন্ট অংশ থাকে না। একটি পূর্ণসংখ্যার আক্ষরিকের একটি উপসর্গ থাকতে পারে যা এর ভিত্তি এবং তার প্রকারটি নির্দিষ্ট করে এমন একটি প্রত্যয় যুক্ত করে।

...

একটি পূর্ণসংখ্যা আক্ষরিকের প্রকারটি সংশ্লিষ্ট তালিকার প্রথম যা তার মান উপস্থাপন করতে পারে।

এখানে চিত্র বর্ণনা লিখুন

যদি কোনও পূর্ণসংখ্যার আক্ষরিক তার তালিকার কোনও প্রকারের দ্বারা প্রতিনিধিত্ব করা না যায় এবং একটি বর্ধিত পূর্ণসংখ্যার প্রকার (3.9.1) এর মান উপস্থাপন করতে পারে, তবে এটিতে বাড়ানো পূর্ণসংখ্যার প্রকার থাকতে পারে। আক্ষরিক জন্য তালিকার সমস্ত প্রকারের মধ্যে স্বাক্ষর থাকলে বর্ধিত পূর্ণসংখ্যার প্রকারে স্বাক্ষর করা হবে। আক্ষরিক জন্য তালিকার সমস্ত প্রকারের স্বাক্ষরবিহীন থাকলে, বর্ধিত পূর্ণসংখ্যার প্রকারের স্বাক্ষর স্বাক্ষরিত হবে। যদি তালিকায় স্বাক্ষরযুক্ত এবং স্বাক্ষরযুক্ত উভয় প্রকারের থাকে তবে বর্ধিত পূর্ণসংখ্যার প্রকারটি স্বাক্ষরিত বা স্বাক্ষরবিহীন হতে পারে। কোনও প্রোগ্রাম দু'টি তৈরি হয় যদি এর কোনও অনুবাদ ইউনিটে একটি পূর্ণসংখ্যার আক্ষরিক থাকে যা অনুমোদিত ধরণের কোনও দ্বারা প্রতিনিধিত্ব করা যায় না।

এবং মানগুলিতে পূর্ণসংখ্যার জন্য এগুলি প্রচারের নিয়ম।

4.5 ইন্টিগ্রাল প্রচার [প্রত্যয়

একটি পূর্ণসংখ্যা ছাড়া অন্য ধরনের prvalue bool, char16_t, char32_t, অথবা wchar_tযার পূর্ণসংখ্যা রূপান্তর ক্রম (4.13) int- এ পদে চেয়ে কম হয় ধরনের prvalue রূপান্তরিত করা যেতে পারে intযদি intউৎস ধরনের সমস্ত মান উপস্থাপন করতে পারেন; অন্যথায়, উত্স মূল্যকে প্রকারের ধরণের রূপান্তরিত করা যেতে পারে unsigned int


3
@ qPCR4vir: ইন C89 / 90 কম্পাইলার ব্যবহার ধরনের কথা ছিলো int, long int, unsigned long intunsuffixed দশমিক ধ্রুবক প্রতিনিধিত্ব করতে। এই একমাত্র ভাষা ছিল যা অসমাপ্ত দশমিক ধ্রুবকগুলির জন্য স্বাক্ষরযুক্ত প্রকারের ব্যবহারের অনুমতি দেয়। সি ++ 98 এ ছিল intবা long int। কোনও স্বাক্ষরবিহীন প্রকারের অনুমতি নেই। সি (সি 99 থেকে শুরু করে) বা সি ++ উভয়ই এই প্রসঙ্গে স্বাক্ষরযুক্ত প্রকারগুলি ব্যবহারের জন্য সংকলককে অনুমতি দেয় না। আপনার সংকলক অবশ্যই স্বাক্ষরযুক্ত প্রকারগুলি ব্যবহারে নির্দ্বিধায় স্বাক্ষরযুক্তগুলির মধ্যে কেউ কাজ না করে থাকলেও এটি এখনও অবধারিত আচরণের একটি নির্দিষ্ট প্রকাশ।
এএনটি

অ্যান্ড্রেটি গ্রেট! কুউস, আপনার অনড়তা। ভিসি ২০১২ টি কি ভেঙে গেছে?
qPCR4vir

@ qPCR4vir: AFAIK, VC2012 এখনও C ++ 11 সংকলক নয় (এটি?), যার অর্থ এটি ব্যবহার করতে হবে intবা long intউপস্থাপন করতে হবে 2147483648। এছাড়াও, আফাইক, ভিসি ২০১২ তে উভয় intএবং long int32-বিট প্রকারের। এর অর্থ হ'ল ভিসি ২০১২-তে আক্ষরিক অনির্ধারিত আচরণের2147483648 দিকে নিয়ে যাওয়া উচিত । আচরণটি যখন অপরিবর্তিত থাকে, সংকলকটিকে কিছু করার অনুমতি দেওয়া হয়। এর অর্থ হ'ল ভিসি ২০১২ টি ভাঙ্গা হয়নি। এটি কেবল একটি বিভ্রান্তিমূলক ডায়াগনস্টিক বার্তা জারি করেছে। আপনাকে আচরণটি অপরিজ্ঞাত করে দেওয়ার পরিবর্তে স্বাক্ষরবিহীন প্রকারটি ব্যবহার করার সিদ্ধান্ত নিয়েছে।
এএনটি

@ অ্যান্ড্রেটি: আপনি কি বলছেন যে যদি সংস্থাগুলি সুনির্দিষ্ট দশমিক আক্ষরিক যা একটি স্বাক্ষরের সর্বোচ্চ মানকে অতিক্রম করে longএবং ডায়াগনস্টিক জারি করার প্রয়োজন না হয় তবে যদি অনুনাসিক দৈত্য নির্গত করতে মুক্ত হয় ? ভাঙা মনে হবে।
সুপারক্যাট

ভিএস ২০০৮-তে একই "সতর্কতা সি 4146" এবং জি ++
স্পেসার

6

সংক্ষেপে, 2147483648উপচে প্রবাহিত হয় -2147483648এবং (-(-2147483648) > 0)হয় true

2147483648বাইনারি মধ্যে এটি দেখতে কেমন লাগে।

এছাড়াও, স্বাক্ষরিত বাইনারি গণনার ক্ষেত্রে, সর্বাধিক উল্লেখযোগ্য বিট ("এমএসবি") হচ্ছে সাইন বিট। এই প্রশ্নটি কেন তা ব্যাখ্যা করতে সহায়তা করতে পারে।


4

কারণ -2147483648প্রকৃতপক্ষে 2147483648অবহেলা (- ) এটিকে প্রয়োগ, সংখ্যা আপনি আশা করতে চাই কি না হয়। এটি আসলে এই সিউডোকোডের সমতুল্য:operator -(2147483648)

এখন ধরে নেওয়া, আপনার সংকলকটির sizeof(int)সমান 4এবং CHAR_BITএটি সংজ্ঞায়িত হয়েছে 8, এটি 2147483648একটি পূর্ণসংখ্যার সর্বাধিক স্বাক্ষরিত মানকে ওভারফ্লোতে পরিণত করবে (2147483647 ) । সুতরাং সর্বোচ্চ প্লাস এক কি? 4 বিট, 2 এস প্রশংসা পূর্ণসংখ্যার সাথে এটির কাজ করতে দেয়।

অপেক্ষা কর 8 পূর্ণসংখ্যার উপচে পড়ে! আমরা কি করি? এর স্বাক্ষরযুক্ত স্বাক্ষরিত উপস্থাপনা ব্যবহার করুন 1000এবং বিটগুলিকে স্বাক্ষরিত পূর্ণসংখ্যা হিসাবে ব্যাখ্যা করুন। এই উপস্থাপনাটি -82s পরিপূরক অবহেলা প্রয়োগ করার ফলে আমাদের ছেড়ে যায় 8, যা আমরা সবাই জানি, এর চেয়েও বড় 0

এই কারণেই <limits.h>(এবং <climits>) সাধারণত সংজ্ঞায়িত হয়INT_MIN হিসাবে হয় ((-2147483647) - 1)- যাতে সর্বাধিক স্বাক্ষরিত পূর্ণসংখ্যা ( 0x7FFFFFFF) অবহেলিত হয় ( 0x80000001), তারপরে হ্রাস ( 0x80000000)।


একটি 4 বিট সংখ্যার জন্য, দুটির পরিপূরক অবহেলা -8এখনও অবধি -8
বেন ভয়েগট

যে -8 ব্যতীত 0-8 হিসাবে ব্যাখ্যা করা হবে, নেতিবাচক নয় 8 এবং 8 টি 4 বিট স্বাক্ষরিত ইনট্রোয়েড
কোল জনসন

-(8)সি ++ এর মধ্যে কোনটি একইরূপে বিবেচনা করুন -8- এটি আক্ষরিক ক্ষেত্রে প্রয়োগ করা হয়, নেতিবাচক আক্ষরিক নয়। আক্ষরিক এটি 8, যা স্বাক্ষরিত 4-বিট পূর্ণসংখ্যায় ফিট করে না, তাই এটি অবশ্যই স্বাক্ষরবিহীন হওয়া উচিত। প্যাটার্নটি হ'ল 1000। এখনও পর্যন্ত আপনার উত্তরটি সঠিক। 10004 বিটের মধ্যে দুটির পরিপূরক অবহেলা হ'ল 1000, এটি স্বাক্ষরিত বা স্বাক্ষরযুক্ত নয় তা বিবেচ্য নয়। আপনার উত্তর বলে, "বিটগুলি একটি স্বাক্ষরিত পূর্ণসংখ্যা হিসাবে ব্যাখ্যা করুন" যা -8দুজনের পরিপূরক অবহেলার পরে মানটিকে যেমন উপকারের আগে করেছিল তেমন করে তোলে ।
বেন ভয়েগট

অবশ্যই, "4-বিট সি ++" তে কোনও "বিটকে স্বাক্ষরিত পূর্ণসংখ্যার পদক্ষেপ হিসাবে ব্যাখ্যা করা যায় না"। আক্ষরিক এটি ক্ষুদ্রতম প্রকারে পরিণত হয় যা এটি প্রকাশ করতে পারে যা স্বাক্ষরযুক্ত 4-বিট পূর্ণসংখ্যার । আক্ষরিক মান হয় 8। নেগেশন প্রয়োগ করা হয় (মডুলো 16), যার চূড়ান্ত উত্তর হয় 8। এনকোডিংটি এখনও 1000 তবে মান স্বাক্ষর না করায় একটি স্বাক্ষরযুক্ত প্রকারটি বেছে নেওয়া হয়েছিল।
বেন ভয়েগট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.