c++ - tutorial - (একটি &#xFF) এর চেয়ে(% 256) আলাদা কেন?



the c++ programming language (4)

আমি সর্বদা ধরে নিয়েছিলাম যে (a % 256) করার সময় অপ্টিমাইজার স্বাভাবিকভাবেই একটি দক্ষ বিটওয়াইজ অপারেশন ব্যবহার করবে, যেন আমি লিখেছি (a & 0xFF)

সংকলক এক্সপ্লোরার gcc-6.2 (-O3) এ পরীক্ষা করার সময়:

// Type your code here, or load an example.
int mod(int num) {
    return num % 256;
}

mod(int):
    mov     edx, edi
    sar     edx, 31
    shr     edx, 24
    lea     eax, [rdi+rdx]
    movzx   eax, al
    sub     eax, edx
    ret

এবং অন্যান্য কোড চেষ্টা করার সময়:

// Type your code here, or load an example.
int mod(int num) {
    return num & 0xFF;
}

mod(int):
    movzx   eax, dil
    ret

দেখে মনে হচ্ছে আমি পুরোপুরি কিছু মিস করছি। কোন ধারনা?

https://code.i-harness.com


সংক্ষিপ্ত উত্তর

-1 % 256 ফলন -1 এবং 255 নয় যা -1 & 0xFF । অতএব, অপটিমাইজেশনটি ভুল হবে।

দীর্ঘ উত্তর

সি ++ এর কনভেনশন রয়েছে যে (a/b)*b + a%b == a , যা বেশ স্বাভাবিক বলে মনে হচ্ছে। a/b সর্বদা ভগ্নাংশের অংশ ছাড়াই পাটিগণিত ফলাফল প্রদান করে (0 এর দিকে কাটা)। ফলস্বরূপ, a%b এর একই চিহ্নটি 0 বা 0 হয়।

উপরের শর্তটি পূরণ করার জন্য বিভাগ -1/256 0 এবং তাই -1%256 অবশ্যই (-1%256)*256 + -1%256 == -1 )। এটি স্পষ্টতই -1&0xFF যা -1&0xFF থেকে পৃথক। অতএব, সংকলকটি আপনার পছন্দ মতো অনুকূলিতকরণ করতে পারে না।

N4606 হিসাবে সি ++ স্ট্যান্ডার্ড [এক্সফারমুলুল §4] এর সম্পর্কিত বিভাগটি উল্লেখ করেছে:

অবিচ্ছেদ্য অপারেন্ডগুলির জন্য / অপারেটর বাতিল হওয়া কোনও ভগ্নাংশের সাথে বীজগণিত ভাগফল দেয়; যদি ভাগের a/b ফলাফলের ধরণের ক্ষেত্রে উপস্থাপনযোগ্য হয়, (a/b)*b + a%b এর সমান [...]।

অপ্টিমাইজেশন সক্ষম করা

তবে unsigned প্রকারগুলি ব্যবহার করে , উপরোক্ত সম্মেলনটি সন্তুষ্ট করে অনুকূলকরণটি সম্পূর্ণ সঠিক হবে :

unsigned(-1)%256 == 0xFF

এটি দেখুন।

অন্যান্য ভাষাসমূহ

আপনি Wikipedia সন্ধান করতে পারেন এটি বিভিন্ন প্রোগ্রামিং ভাষাতে একেবারেই আলাদাভাবে পরিচালনা করা হয়।


এটি একই না. num = -79 চেষ্টা করুন, এবং আপনি উভয় ক্রিয়াকলাপ থেকে পৃথক ফলাফল পাবেন। (-79) % 256 = -79 , যখন (-79) & 0xff কিছু ধনাত্মক সংখ্যা।

unsigned int ব্যবহার করে, ক্রিয়াকলাপগুলি একই রকম হয় এবং কোড সম্ভবত একই হবে।

পিএস- কেউ মন্তব্য করেছেন

সেগুলি একই হওয়া উচিত নয়, a % b কে a - b * floor (a / b) হিসাবে সংজ্ঞায়িত করা হয়।

এটি কীভাবে এটি সি, সি ++, অবজেক্টিভ-সি (সংজ্ঞায়িত কোডটি সংকলন করবে এমন সমস্ত ভাষায়) সংজ্ঞায়িত হয় না।


যেহেতু সি ++ 11, num % 256 num হলে অ-ধনাত্মক হতে হবে।

সুতরাং বিট প্যাটার্নটি আপনার সিস্টেমে স্বাক্ষরিত ধরণের প্রয়োগের উপর নির্ভর করবে: নেতিবাচক প্রথম যুক্তির জন্য, ফলাফলটি সর্বনিম্ন উল্লেখযোগ্য 8 বিটের নিষ্কাশন নয়।

আপনার ক্ষেত্রে নামটি unsigned না করা থাকলে এটি আলাদা বিষয় হবে: আজকাল আমি প্রায়শই একটি সংকলক আশা করছিলাম যে আপনি যে অপটিমাইজেশনটি উদ্ধৃত করেছেন তা তৈরি করবে।


সংকলকের যুক্তিতে আমার টেলিপ্যাথিক অন্তর্দৃষ্টি নেই, তবে % এর ক্ষেত্রে নেতিবাচক মানগুলি (এবং শূন্যের দিকে বিভাজনগুলি) নিয়ে কাজ করার প্রয়োজনীয়তা রয়েছে, এবং ফলাফলটি সর্বদা কম 8 বিট থাকে।

sar নির্দেশ আমার কাছে "শিফট পাটিগণিত ডান" এর মতো শোনায়, সাইন বিট মান সহ শূন্য বিটগুলি পূরণ করে।





optimization