((A + (খ & 255)) এবং 255) ((a + b) এবং 255) এর মতো?


92

আমি কিছু সি ++ কোড ব্রাউজ করছিলাম এবং এর মতো কিছু পেয়েছি:

(a + (b & 255)) & 255

দ্বিগুণ এবং আমাকে বিরক্ত করেছে, তাই আমি ভেবেছিলাম:

(a + b) & 255

( aএবং b32-বিট স্বাক্ষরবিহীন পূর্ণসংখ্যাগুলি)

আমার তত্ত্বটি নিশ্চিত করতে আমি দ্রুত একটি পরীক্ষা স্ক্রিপ্ট (জেএস) লিখেছিলাম:

for (var i = 0; i < 100; i++) {
    var a = Math.ceil(Math.random() * 0xFFFF),
        b = Math.ceil(Math.random() * 0xFFFF);

    var expr1 = (a + (b & 255)) & 255,
        expr2 = (a + b) & 255;

    if (expr1 != expr2) {
        console.log("Numbers " + a + " and " + b + " mismatch!");
        break;
    }
}

যদিও স্ক্রিপ্টটি আমার অনুমানকে নিশ্চিত করেছে (উভয় ক্রিয়াকলাপ সমান), তবুও আমি এটি বিশ্বাস করি না, কারণ 1) এলোমেলো এবং 2) আমি গণিতবিদ নই, আমি কী করছি তা আমার কোনও ধারণা নেই

এছাড়াও, লিসপ-ওয়াইয়ের শিরোনামের জন্য দুঃখিত। এটি সম্পাদনা করতে নির্দ্বিধায়।


4
সেই লিপিটি কোন ভাষা? না Math.random()একটি পূর্ণসংখ্যা অথবা একটি ডবল এ [0,1) আসতে? আমি মনে করি না যে আপনার লিপিটি (আমি বলতে পারি সেরা) আপনি যে সমস্যার সমাধান করেছেন তা প্রতিফলিত করে।
ইট

7
সি / সি ++ কোড কী? তারা বিভিন্ন laauauges হয়।
আবহাওয়া ভেন

14
আপনি জেএস-তে পরীক্ষা করার চেষ্টা করছেন এমন আচরণটি আপনি পুনরুত্পাদন করতে পারবেন না। এজন্য প্রত্যেকেই ভাষা পছন্দ সম্পর্কে কেবল আপনিই। জেএস দৃ strongly়ভাবে টাইপ করা হয়নি এবং উত্তরটি সি / সি ++ এর ভেরিয়েবলের ধরণের উপর সমালোচনামূলকভাবে নির্ভর করে। আপনি যে প্রশ্নটি করেছেন তা জেএস সম্পূর্ণ বোকা is
ইট

4
@ ওয়েদারভেইন জাভাস্ক্রিপ্ট ফাংশনটির নাম ব্যবহার করে এটি প্রয়োজনীয় সিউডো কোড। তার প্রশ্নটি সি এবং সি ++ তে স্বাক্ষরবিহীন পূর্ণসংখ্যার আচরণ &এবং সম্পর্কে +
বারমার

11
মনে রাখবেন যে "আমি একটি পরীক্ষা প্রোগ্রাম লিখেছি এবং সমস্ত সম্ভাব্য ইনপুটগুলির জন্য আমার প্রত্যাশিত উত্তরটি পেয়েছি" আসলে কোনও গ্যারান্টি নয় যে কোনও কিছু আপনার প্রত্যাশা অনুযায়ী আচরণ করে। অপরিজ্ঞাত আচরণটি এর মতো বাজে হতে পারে; আপনার কোডটি সঠিক বলে নিজেকে নিশ্চিত করার পরে কেবল অপ্রত্যাশিত ফলাফল দেওয়া।

উত্তর:


78

তারা একই. একটি প্রমাণ এখানে:

প্রথমে পরিচয়টি নোট করুন (A + B) mod C = (A mod C + B mod C) mod C

এর a & 255জন্য দাঁড়িয়ে হিসাবে সমস্যা পুনরায় করা যাক a % 256aস্বাক্ষরহীন থাকায় এটি সত্য ।

তাই (a + (b & 255)) & 255হয়(a + (b % 256)) % 256

এটি একই রকম (a % 256 + b % 256 % 256) % 256(আমি উপরে বর্ণিত পরিচয়টি প্রয়োগ করেছি: নোট করুন modএবং %স্বাক্ষরযুক্ত প্রকারের সমতুল্য))

এটি সহজ (a % 256 + b % 256) % 256হয়ে যায় যা হয়ে যায় (a + b) % 256(পরিচয়টি পুনরায় প্রয়োগ করে)। তারপরে আপনি বিটওয়াইজ অপারেটরটিকে আবার দিতে পারেন

(a + b) & 255

প্রমাণ শেষ।


81
এটি গাণিতিক প্রমাণ, অতিরিক্ত প্রবাহের সম্ভাবনা উপেক্ষা করে। বিবেচনা করুন A=0xFFFFFFFF, B=1, C=3। প্রথম পরিচয়টি ধরে না। (স্বাক্ষরযুক্ত পাটিগণিতের জন্য ওভারফ্লো কোনও সমস্যা হয়ে উঠবে না, তবে এটি কিছুটা আলাদা বিষয়))
আলেকসডি

4
আসলে, (a + (b & 255)) & 255একই হিসাবে (a + (b % 256)) % N % 256, যেখানে Nসর্বোচ্চ স্বাক্ষরবিহীন মানের চেয়ে এক বড়। (পরবর্তী সূত্রটি গাণিতিক পূর্ণসংখ্যার গাণিতিক হিসাবে ব্যাখ্যা করা বোঝানো হয়েছে)

17
এর মতো গাণিতিক প্রমাণ কম্পিউটার আর্কিটেকচারে পূর্ণসংখ্যার আচরণ প্রমাণ করার জন্য উপযুক্ত নয়।
জ্যাক এইডলি

25
@ জ্যাকএইডলি: সঠিকভাবে সম্পন্ন করার সময় এগুলি উপযুক্ত (যা ওভারফ্লো বিবেচনায় অবহেলার কারণে নয়) appropriate

4
@ শ্যাজ: এটি পরীক্ষার স্ক্রিপ্টের সত্য, তবে জিজ্ঞাসিত প্রশ্নের অংশ নয়।

21

স্বাক্ষরযুক্ত ফলাফল আনতে অবস্থানগত সংযোজন, বিয়োগফল এবং স্বাক্ষরযুক্ত সংখ্যাগুলির গুণনের ক্ষেত্রে, ইনপুটটির আরও উল্লেখযোগ্য অঙ্কগুলি ফলাফলের কম-উল্লেখযোগ্য অঙ্কগুলিকে প্রভাবিত করে না। এটি বাইনারি গাণিতিকের ক্ষেত্রে যতটা দশমিক গাণিতিকের ক্ষেত্রে এটি প্রযোজ্য। এটি "দ্বিগুণ পরিপূরক" স্বাক্ষরিত গাণিতিকের ক্ষেত্রেও প্রযোজ্য, তবে স্বাক্ষরিত গাণিতিকের সাইন-প্রবণতা নয়।

তবে বাইনারি পাটিগণিত থেকে নিয়ম গ্রহণ এবং সেগুলিকে সি তে প্রয়োগ করার সময় আমাদের সতর্কতা অবলম্বন করতে হবে (আই বিলিভ সি ++ এই স্টাফটিতে সি হিসাবে একই নিয়ম রয়েছে তবে আমি 100% নিশ্চিত নই) কারণ সি গাণিতিকের কিছু আরকান বিধি রয়েছে যা আমাদের ভ্রমণ করতে পারে আপ সি-তে স্বাক্ষরিত পাটিগণিতগুলি সহজ বাইনারি রেকারপাউন্ড বিধি অনুসরণ করে তবে স্বাক্ষরিত গাণিতিক ওভারফ্লো অনির্ধারিত আচরণ। আরও খারাপ পরিস্থিতিতে কিছু সি স্বাক্ষরিত স্বাক্ষরিত টাইপ (স্বাক্ষরিত) এর জন্য স্বয়ংক্রিয়ভাবে "প্রচার" করবে।

সি তে অপরিজ্ঞাত আচরণ বিশেষত কূটকীয় হতে পারে। একটি বোবা সংকলক (বা কম অপ্টিমাইজেশন স্তরের একটি সংকলক) বাইনারি গাণিতিক সম্পর্কে আপনার বোঝার ভিত্তিতে আপনি যা প্রত্যাশা করেছিলেন তা করতে পারে যখন একটি অনুকূলকরণ সংকলক আপনার কোডটি অদ্ভুত উপায়ে ভেঙে দিতে পারে।


সুতরাং প্রশ্নের সূত্রে ফিরে আসার সামঞ্জস্য অপারেন্ডের ধরণের উপর নির্ভর করে।

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

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

যদি তারা স্বাক্ষরিত পূর্ণসংখ্যার আকার যার আকারের চেয়ে কম থাকে তবে আবার ওভারফ্লো হতে পারে না এবং দ্বিগুণ-পরিপূরক বাস্তবায়নের ক্ষেত্রে আমরা মানক বাইনারি গাণিতিক যুক্তির উপর নির্ভর করতে পারি যে তারা সামঞ্জস্যপূর্ণ। সাইন-প্রস্থে বা এগুলি বাস্তবায়নের পরিপূরক হয় তবে তারা সমতুল্য হবে না।

OTOH aএবং যদি এর bপূর্ণসংখ্যার সাথে স্বাক্ষরিত হয় যার আকার বড় আকারের চেয়ে বড় বা সমান হয় তবে এমনকি দ্বিগুণ পরিপূরক বাস্তবায়নের ক্ষেত্রেও এমন একটি ক্ষেত্রে রয়েছে যেখানে একটি বিবৃতি ভালভাবে সংজ্ঞায়িত হবে এবং অন্যটি অপরিজ্ঞাত আচরণ হবে।


20

লেমা: a & 255 == a % 256স্বাক্ষরবিহীন জন্যa

সাইন করা হয়নি aহিসেবে পুনর্লিখিত করা যেতে পারে m * 0x100 + bকিছু স্বাক্ষরবিহীন m, b, 0 <= b < 0xff, 0 <= m <= 0xffffff। এটি উভয় সংজ্ঞা থেকে অনুসরণ করে যে a & 255 == b == a % 256

অতিরিক্তভাবে, আমাদের প্রয়োজন:

  • বিতরণ সম্পত্তি: (a + b) mod n = [(a mod n) + (b mod n)] mod n
  • স্বাক্ষরবিহীন সংযোজনের সংজ্ঞা, গাণিতিকভাবে: (a + b) ==> (a + b) % (2 ^ 32)

এইভাবে:

(a + (b & 255)) & 255 = ((a + (b & 255)) % (2^32)) & 255      // def'n of addition
                      = ((a + (b % 256)) % (2^32)) % 256      // lemma
                      = (a + (b % 256)) % 256                 // because 256 divides (2^32)
                      = ((a % 256) + (b % 256 % 256)) % 256   // Distributive
                      = ((a % 256) + (b % 256)) % 256         // a mod n mod n = a mod n
                      = (a + b) % 256                         // Distributive again
                      = (a + b) & 255                         // lemma

হ্যাঁ, এটা সত্য। 32-বিট স্বাক্ষরযুক্ত পূর্ণসংখ্যার জন্য।


অন্যান্য পূর্ণসংখ্যার প্রকার সম্পর্কে কী?

  • 64-বিট স্বাক্ষরবিহীন পূর্ণসংখ্যার জন্য, সব উপরে ঠিক যেমন ভাল প্রযোজ্য, শুধু বদলে 2^64জন্য 2^32
  • 8- এবং 16-বিট স্বাক্ষরবিহীন পূর্ণসংখ্যার জন্য, এর সাথে প্রচারের সাথে জড়িত int। এটি intঅবশ্যই অপ্রবাহিত হবে না বা এই কোনও কার্যক্রমে নেতিবাচক হবে না, সুতরাং সেগুলি সমস্ত বৈধ থাকবে।
  • জন্য স্বাক্ষরিত পূর্ণসংখ্যার, যদি পারেন a+bবা a+(b&255)ওভারফ্লো, এটা অনির্ধারিত আচরণ। সুতরাং সাম্যতা ধরে রাখতে পারে না - এমন কিছু ক্ষেত্রে রয়েছে যেখানে (a+b)&255অপরিজ্ঞাত আচরণ হয় তবে তা (a+(b&255))&255হয় না।

17

হ্যাঁ, (a + b) & 255ঠিক আছে।

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


উপরেরটি সবসময় সত্য নয়, সি ++ স্ট্যান্ডার্ড এমন একটি বাস্তবায়নকে অনুমতি দেয় যা এটি ভেঙে দেয়।

এই জাতীয় ডেথস্টেশন 9000 : - )int ওপিকে unsigned short"32-বিট স্বাক্ষরবিহীন পূর্ণসংখ্যার" দিয়ে বোঝায়, 33-বিট ব্যবহার করতে হবে । যদি unsigned intবোঝানো হয়, ডিএস 9 কে int32-বিট unsigned intএবং একটি প্যাডিং বিট সহ 32-বিট ব্যবহার করতে হবে । (স্বাক্ষরবিহীন পূর্ণসংখ্যার signed3.9.1 / 3 অনুযায়ী তাদের স্বাক্ষরিত অংশগুলির মতো একই আকারের প্রয়োজন, এবং প্যাডিং বিটগুলি §3.9.1 / 1 এ অনুমোদিত)) আকার এবং প্যাড বিটের অন্য সংমিশ্রণগুলিও কাজ করবে।

আমি যতদূর বলতে পারি, এটি ভাঙার একমাত্র উপায় এটি কারণ:

  • পূর্ণসংখ্যার প্রতিনিধিত্ব অবশ্যই একটি "বিশুদ্ধ বাইনারি" এনকোডিং স্কিম ব্যবহার করতে হবে (.93.9.1 / 7 এবং পাদটীকা), প্যাডিং বিট এবং সাইন বিট ব্যতীত সমস্ত বিট অবশ্যই 2 এন এর মান অবদান রাখতে হবে
  • intউত্স প্রচার কেবলমাত্র যদি উত্স ধরণের সমস্ত মান (.54.5 / 1) উপস্থাপন করতে পারে তবে অনুমোদিত হতে intহবে কমপক্ষে কমপক্ষে 32 বিট অবধি , এবং একটি চিহ্ন বিট to
  • intঅধিক মূল্য বিট থাকতে পারে না 32 তুলনায় (সাইন বিট বেড়ে চলেছে নয়), কারণ অন্য একটি ছাড়াও ওভারফ্লো না।

4
সংযোজন ছাড়াও আরও অনেক অপারেশন রয়েছে যেখানে উচ্চ বিটগুলিতে আবর্জনা আপনার আগ্রহী কম বিটগুলির ফলাফলকে প্রভাবিত করে না 2 এই প্রশ্নোত্তরটি দেখুন 2 এর পরিপূরক সম্পর্কে , যা ব্যবহারের ক্ষেত্রে x86 asm ব্যবহার করে তবে এটি প্রযোজ্য কোন পরিস্থিতিতে স্বাক্ষরযুক্ত বাইনারি পূর্ণসংখ্যার।
পিটার কর্ডেস

4
যদিও অবশ্যই সবার বেনামে নাম লেখার অধিকার, আমি সর্বদা একটি মন্তব্য শেখার সুযোগ হিসাবে প্রশংসা করি।
আলাইন

4
এটি এখন পর্যন্ত বুঝতে সবচেয়ে সহজ উত্তর / যুক্তি, আইএমও। বহন / বিয়োগের সাথে বহন / ঘৃণা শুধুমাত্র বাইনারিতে কম বিট থেকে উচ্চ বিট (ডান থেকে বাম) পর্যন্ত প্রচার করে, দশমিক হিসাবে একই। আইডি কে কেন এটিকে কমিয়ে দেবে।
পিটার কর্ডেস

4
@ বাথশেবা: CHAR_BIT 8 হওয়ার দরকার নেই তবে সি এবং সি ++ তে স্বাক্ষরযুক্ত প্রকারের কিছুটা বিট প্রস্থের সাধারণ বেস 2 বাইনারি পূর্ণসংখ্যার হিসাবে আচরণ করা প্রয়োজন। আমি মনে করি এর জন্য প্রয়োজন যে UINT_MAX 2^N-1। (এনএইচআর_বিটের একাধিক হতেও পারে না, আমি ভুলে যাই, তবে আমি দৃ the়ভাবে নিশ্চিত যে এই স্ট্যান্ডার্ডটির প্রয়োজন হয় যে মোড়কে কিছুটা পাওয়ার মডুলো হয়)) আমি মনে করি আপনি অদ্ভুততা অর্জনের একমাত্র উপায় হ'ল প্রচারের মাধ্যমে স্বাক্ষরিত ধরণ যা যথেষ্ট পরিমাণে বিস্তৃত aবা bযথেষ্ট a+bক্ষেত্রে বিস্তৃত নয় all
পিটার কর্ডেস

4
@ বাথশেবা: হ্যাঁ, ভাগ্যক্রমে সি-হিসাবে-বহনযোগ্য-অ্যাসেম্বলি-ভাষাটি বেশিরভাগই স্বাক্ষরবিহীন প্রকারের জন্য কাজ করে। এমনকি উদ্দেশ্যমূলক-প্রতিকূল সি বাস্তবায়নও এটিকে ভেঙে ফেলতে পারে না। এটি কেবলমাত্র স্বাক্ষরিত ধরণের যেখানে সিগুলিতে সত্যিকারের পোর্টেবল বিট-হ্যাকগুলির জন্য জিনিসগুলি ভয়ঙ্কর এবং ডেথস্টেশন 9000 সত্যিই আপনার কোডটি ভেঙে দিতে পারে।
পিটার কর্ডেস

14

আপনার কাছে ইতিমধ্যে স্মার্ট উত্তর রয়েছে: স্বাক্ষরবিহীন পাটিগণিতটি মডুলো পাটিগণিত এবং ফলস্বরূপ ফলাফলটি অনুষ্ঠিত হবে, আপনি এটি গাণিতিকভাবে প্রমাণ করতে পারবেন ...


কম্পিউটারগুলির সম্পর্কে একটি দুর্দান্ত জিনিস হ'ল কম্পিউটারগুলি দ্রুত। প্রকৃতপক্ষে, তারা এত দ্রুত যে 32 বিটের সমস্ত বৈধ সংমিশ্রণগুলি গণন করা যুক্তিসঙ্গত সময়ে সম্ভব (64৪ বিট দিয়ে চেষ্টা করবেন না)।

সুতরাং, আপনার ক্ষেত্রে, আমি ব্যক্তিগতভাবে এটি কেবল একটি কম্পিউটারে ফেলে দিতে পছন্দ করি; এটা আমার নিজেকে সন্তুষ্ট করার যে প্রোগ্রাম সঠিক চেয়ে নিজেকে সন্তুষ্ট করার চেয়ে গাণিতিক প্রমাণ সঠিক লাগে কম সময় লাগে এবং আমি নির্দেশের মধ্যে বিস্তারিত তত্ত্বাবধান না যে 1 :

#include <iostream>
#include <limits>

int main() {
    std::uint64_t const MAX = std::uint64_t(1) << 32;
    for (std::uint64_t i = 0; i < MAX; ++i) {
        for (std::uint64_t j = 0; j < MAX; ++j) {
            std::uint32_t const a = static_cast<std::uint32_t>(i);
            std::uint32_t const b = static_cast<std::uint32_t>(j);

            auto const champion = (a + (b & 255)) & 255;
            auto const challenger = (a + b) & 255;

            if (champion == challenger) { continue; }

            std::cout << "a: " << a << ", b: " << b << ", champion: " << champion << ", challenger: " << challenger << "\n";
            return 1;
        }
    }

    std::cout << "Equality holds\n";
    return 0;
}

এটি 32-বিট স্পেসের সমস্ত সম্ভাব্য মানগুলির মধ্যে দিয়ে গণনা করে aএবং bসমতা রাখে কি না তা পরীক্ষা করে। যদি এটি না হয় তবে এটি কেসটি প্রিন্ট করে যা কার্যকর হয়নি, যা আপনি স্যানিটি পরীক্ষা হিসাবে ব্যবহার করতে পারেন।

এবং, কলঙ্ক অনুসারে : সাম্যতা ধারণ করে

তদুপরি, পাটিগণিত নিয়মগুলি বিট-প্রস্থের অজোনস্টিক ( intবিট-প্রস্থের উপরে ) রয়েছে, এই সমতাটি uns৪ বিট এবং ১২৮ বিট সহ 32 বিট বা তার বেশি সংখ্যক স্বাক্ষরযুক্ত পূর্ণসংখ্যার জন্য থাকবে।

দ্রষ্টব্য: একটি সংকলক কীভাবে যুক্তিসঙ্গত সময় ফ্রেমে সমস্ত -৪-বিট নিদর্শনগুলি গণনা করতে পারে? এটা হতে পারে না. লুপগুলি অপ্টিমাইজ করা হয়েছিল। অন্যথায় আমরা সকলেই মৃত্যুদণ্ড কার্যকর হওয়ার আগেই মারা যেতাম।


আমি প্রাথমিকভাবে এটি 16-বিট স্বাক্ষরবিহীন পূর্ণসংখ্যার জন্যই প্রমাণ করেছি; দুর্ভাগ্যক্রমে সি ++ একটি উন্মাদ ভাষা যেখানে ছোট পূর্ণসংখ্যার (এর চেয়ে ছোট বিটউইদথ int) প্রথমে রূপান্তরিত হয় int

#include <iostream>

int main() {
    unsigned const MAX = 65536;
    for (unsigned i = 0; i < MAX; ++i) {
        for (unsigned j = 0; j < MAX; ++j) {
            std::uint16_t const a = static_cast<std::uint16_t>(i);
            std::uint16_t const b = static_cast<std::uint16_t>(j);

            auto const champion = (a + (b & 255)) & 255;
            auto const challenger = (a + b) & 255;

            if (champion == challenger) { continue; }

            std::cout << "a: " << a << ", b: " << b << ", champion: "
                      << champion << ", challenger: " << challenger << "\n";
            return 1;
        }
    }

    std::cout << "Equality holds\n";
    return 0;
}

এবং আবারও, কলঙ্ক অনুসারে : সাম্যতা ধারণ করে

ঠিক আছে, আপনি সেখানে যান :)


1 অবশ্যই, যদি কোনও প্রোগ্রাম অজান্তেই অনির্ধারিত আচরণকে ট্রিগার করে, তবে এটি খুব বেশি প্রমাণিত হবে না।


4
আপনি বলছেন 32-বিট মানগুলির সাথে কাজ করা সহজ তবে আসলে 16-বিট ব্যবহার করুন ...: ডি
উইল মেন্টজেল

4
@ উইলি মেন্টজেল: এটি একটি আকর্ষণীয় মন্তব্য। আমি প্রথমে বলতে চেয়েছিলাম যে এটি যদি 16 টি বিট দিয়ে কাজ করে তবে 32 বিট, 64 বিট এবং 128 বিট দিয়ে এটি একই রকম কাজ করবে কারণ স্ট্যান্ডার্ডটির বিট বিট-প্রস্থের জন্য নির্দিষ্ট আচরণ নেই ... তবে আমি মনে করি এটি আসলে করে এর চেয়ে ছোট বিট-প্রস্থের জন্য int: ছোট পূর্ণসংখ্যার প্রথমে int(একটি অদ্ভুত নিয়মে) রূপান্তর করা হয় । সুতরাং আমাকে আসলে 32-বিট দিয়ে বিক্ষোভ করতে হবে (এবং পরে এটি 64 বিট, 128 বিট, ...) পর্যন্ত প্রসারিত হবে।
ম্যাথিউ এম।

4
যেহেতু আপনি সমস্ত (4294967296 - 1) * (4294967296 - 1) সম্ভাব্য ফলাফলগুলি মূল্যায়ন করতে পারবেন না, আপনি কোনওভাবে হ্রাস করবেন? আমি আমার মতামত MAX হওয়া উচিত (4294967296 - 1) আপনি যদি সেই পথে যান তবে এটি আপনার জীবনকালের মধ্যে কখনই শেষ হবে না আপনি যেমন বলেছেন ... সুতরাং, সর্বোপরি আমরা কোনও পরীক্ষায় সাম্যতা প্রদর্শন করতে পারি না, কমপক্ষে আপনার মতো কোনওটিতে নয় not বর্ণনা
উইল মেন্টজেল

4
এটি একটি 2 এর পরিপূরক বাস্তবায়নে পরীক্ষা করে প্রমাণিত হয় না যে এটি ডেথস্টেশন 9000 প্রস্থের প্রস্থের সাথে সাইন-প্রবণতা বা কারও পরিপূরক হিসাবে বহনযোগ্য। উদাহরণস্বরূপ একটি সরু স্বাক্ষরযুক্ত প্রকারটি 17-বিটকে প্রচার করতে পারে intযা প্রতিটি সম্ভাব্য প্রতিনিধিত্ব করতে পারে uint16_tতবে কোথায় a+bওভারফ্লো হতে পারে। স্বাক্ষরযুক্ত প্রকারের চেয়ে সঙ্কুচিতদের জন্য এটি কেবল একটি সমস্যা int; সি প্রয়োজন হয় যে unsignedপ্রকারগুলি বাইনারি পূর্ণসংখ্যার, তাই মোড়কগুলি 2 এর শক্তির আকারে ঘটে
পিটার

4
সি এর নিজের ভালোর জন্য খুব পোর্টেবল হওয়ার বিষয়ে সম্মত। এটা হবে সত্যিই চমৎকার যদি তারা সম্পূরক 2 এর সাইনড জন্য গাণিতিক ডান-বদল আনতে, এবং একটি পথে প্রমিত চাই undefined-আচরণ শব্দার্থবিদ্যা পরিবর্তে মোড়ানো শব্দার্থবিদ্যা সঙ্গে গাণিতিক স্বাক্ষরিত কাজের জন্য, সেই ক্ষেত্রে জন্য যখন আপনি চান মোড়ানো। তারপরে সি পুনরায় একটি পোর্টেবল এসেম্ব্লার হিসাবে কার্যকর হতে পারে, মাইনফিল্ডের পরিবর্তে আধুনিক অপ্টিমাইজ করা সংকলকগুলির জন্য ধন্যবাদ যে এটি কোনও অপরিজ্ঞাত আচরণ ছাড়াই নিরাপদ করে তোলে (কমপক্ষে আপনার টার্গেট প্ল্যাটফর্মের জন্য। কেবল ডেথস্টেশন 9000 বাস্তবায়নে অপরিজ্ঞাত আচরণ ঠিক আছে, আপনি যেমন খুঁজে বের করা).
পিটার কর্ডেস

4

দ্রুত উত্তর হল: উভয় এক্সপ্রেশন সমতুল্য

  • যেহেতু aএবং b32-বিট স্বাক্ষরবিহীন পূর্ণসংখ্যার ফলাফল, ওভারফ্লো ক্ষেত্রেও ফলাফল একই same স্বাক্ষরবিহীন পাটিগণিত এটির গ্যারান্টি দেয়: ফলাফল স্বাক্ষরিত স্বাক্ষর পূর্ণসংখ্যার ধরণের দ্বারা প্রতিনিধিত্ব করা যায় না এমন ফলাফলটি ফলাফলের দ্বারা প্রতিনিধিত্ব করা যায় এমন বৃহত্তম মানের চেয়ে বড় যে সংখ্যাটি হ্রাস করা হয় one

দীর্ঘ উত্তরটি হ'ল: এমন কোনও প্ল্যাটফর্ম নেই যেখানে এই অভিব্যক্তিগুলি পৃথক হবে, তবে অবিচ্ছেদ্য প্রচারের বিধিগুলির কারণে মানক এটির গ্যারান্টি দেয় না।

  • aএবং b(স্বাক্ষরযুক্ত 32 বিট ইন্টিজার) প্রকারের তুলনায় উচ্চতর র‌্যাঙ্ক থাকলে intগণনাটি স্বাক্ষরবিহীন হিসাবে তৈরি করা হয়, মডুলো 2 32 , এবং এটি সমস্ত মান এবং aএবং উভয়ের জন্য উভয় মত প্রকাশের জন্য একই সংজ্ঞায়িত ফলাফল দেয় b

  • বিপরীতভাবে, যদি এর প্রকার aএবং এর bচেয়ে ছোট হয় তবে intউভয়কে পদোন্নতি দেওয়া হয় intএবং স্বাক্ষরিত গাণিতিক ব্যবহার করে গণনা করা হয়, যেখানে ওভারফ্লো অনির্ধারিত আচরণের ডাক দেয়।

    • যদি intকমপক্ষে 33 টি মান বিট থাকে তবে উপরের এক্সপ্রেশনগুলির মধ্যে কোনওটিই উপচে পড়তে পারে না, ফলে ফলাফলটি পুরোপুরি সংজ্ঞায়িত হয় এবং উভয় এক্সপ্রেশনগুলির জন্য একই মান থাকে।

    • তাহলে intঠিক 32 মান বিট আছে, কম্পিউটেশন করতে জন্য ওভারফ্লো উভয় উদাহরণ মানের জন্য এক্সপ্রেশন, a=0xFFFFFFFFএবং b=1উভয় এক্সপ্রেশন মধ্যে একটি ওভারফ্লো কারণ হবে। এটি এড়াতে আপনার লিখতে হবে ((a & 255) + (b & 255)) & 255

  • সুখবরটি হ'ল এরকম কোনও প্ল্যাটফর্ম নেই 1


1 আরও স্পষ্ট করে বলতে গেলে , এ জাতীয় আসল প্ল্যাটফর্ম উপস্থিত নেই, তবে এমন একটি আচরণ প্রদর্শনের জন্য একটি DS9K কনফিগার করতে পারে এবং সি স্ট্যান্ডার্ডের সাথে খাপ খায়


4
আপনার ২ য় সাবউবলেটটি প্রয়োজন (1) এর aচেয়ে ছোট int(2) intএর 32 টি মান বিট (3) a=0xFFFFFFFF। এগুলি সব সত্য হতে পারে না।
ব্যারি

4
@ ব্যারি: যে সমস্ত ক্ষেত্রে প্রয়োজনীয়তা পূরণ হয় বলে মনে হয় তা হল 33-বিট int, যেখানে 32 মান বিট এবং একটি চিহ্ন বিট রয়েছে।
বেন ভয়েগট

2

কোনও ওভারফ্লো অনুমান করে সমান । কোনও সংস্করণই ওভারফ্লোতে সত্যই প্রতিরোধী নয় তবে ডাবল এবং সংস্করণ এটির চেয়ে বেশি প্রতিরোধী। আমি এমন কোনও সিস্টেম সম্পর্কে সচেতন নই যেখানে এই ক্ষেত্রে একটি ওভারফ্লো একটি সমস্যা তবে আমি লেখককে দেখতে পাচ্ছি যে এটির ক্ষেত্রে এটি রয়েছে।


4
ওপিতে নির্দিষ্ট করা হয়েছে: (এ এবং বি 32-বিট স্বাক্ষরযুক্ত ইন্টিজারগুলি) । যদি না int33 বিট চওড়া, ফলে একই এমনকি ওভারফ্লো ক্ষেত্রে। স্বাক্ষরবিহীন পাটিগণিত এটির গ্যারান্টি দেয়: ফলাফল স্বাক্ষরিত স্বাক্ষর পূর্ণসংখ্যার ধরণের দ্বারা প্রতিনিধিত্ব করা যায় না এমন ফলাফলটি ফলাফলের দ্বারা প্রতিনিধিত্ব করা যায় এমন বৃহত্তম মানের চেয়ে বড় যে সংখ্যাটি হ্রাস করা হয় one
chqrlie

2

হ্যাঁ আপনি এটি পাটিগণিত দিয়ে প্রমাণ করতে পারেন, তবে আরও স্বজ্ঞাত উত্তর রয়েছে।

যুক্ত করার সময়, প্রতিটি বিট কেবল সেগুলি নিজের থেকে বেশি তাৎপর্যপূর্ণভাবে প্রভাবিত করে; যারা কম তাড়াতাড়ি না।

অতএব, সংযোজনের আগে আপনি উচ্চতর বিটগুলিতে যা কিছু করুন ফলাফল পরিবর্তিত হবে না, যতক্ষণ না আপনি কেবলমাত্র বিটগুলি সর্বনিম্ন বিট সংশোধিতের চেয়ে কম গুরুত্বপূর্ণ রাখেন।


0

প্রমাণটি তুচ্ছ এবং পাঠকের জন্য অনুশীলন হিসাবে রেখে দেওয়া হয়েছে

তবে এটির উত্তর হিসাবে বৈধতা দেওয়ার জন্য আপনার প্রথম লাইনের কোড বলছে b** এর শেষ 8 টি বিট ( bশূন্যে সেট করার সমস্ত উচ্চ বিট ) নিন এবং এটিকে যুক্ত করুন aএবং তারপরে সমস্ত উচ্চতর ফলাফলের মাত্র 8 টি বিট নিন বিট শূন্য।

দ্বিতীয় লাইনটি যুক্ত করে যোগ করুন aএবং bসমস্ত উচ্চতর বিট শূন্য সহ শেষ 8 টি বিট নিন।

ফলাফলের জন্য কেবলমাত্র সর্বশেষ 8 টি বিট উল্লেখযোগ্য। অতএব কেবলমাত্র শেষ 8 টি বিট ইনপুট (গুলি) -র ক্ষেত্রে তাৎপর্যপূর্ণ।

** শেষ 8 বিট = 8 এলএসবি

এছাড়াও আকর্ষণীয় যে আউটপুট সমান হবে

char a = something;
char b = something;
return (unsigned int)(a + b);

উপরের হিসাবে, কেবল 8 টি এলএসবি তাৎপর্যপূর্ণ তবে ফলাফলটি unsigned intঅন্য সমস্ত বিট শূন্যের সাথে একটি । a + bওভারফ্লো করবে বলে আশা করা ফলাফলের উত্পাদক।


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