কেন যদি (n & -n) == n তবে n 2 এর শক্তি?


84

Java.util.Random উৎস লাইন 294 বলেছেন

if ((n & -n) == n) // i.e., n is a power of 2
    // rest of the code

কেন?


4
নতুন ট্যাগটি একটি ইঙ্গিত হওয়া উচিত। :)
bzlm


4
বিট অনুসরণ করুন। প্রসঙ্গত, এটি দুটি হিসাবে একটি শক্তি হিসাবে শূন্যকেও গণনা করে। সূত্রটিও (n & (n - 1)) == 0কাজ করে (এটি সর্বনিম্ন অর্ডার বিটটি সরিয়ে দেয়, যদি কোনও বিট না থাকে তবে প্রথমে সর্বাধিক 1 বিট সেট থাকে)।
13:51 এ 16

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

4
অপেক্ষা করুন, সবাই কি আজকাল java.util.Random উত্স থেকে পড়ছেন? (আমি এটি কয়েক মাস আগে পড়েছি এবং তখন থেকে এসও-তে এ সম্পর্কে কয়েকটি প্রশ্ন আমার মনে আছে))
মতিন উলহাক

উত্তর:


48

বর্ণনাটি পুরোপুরি নির্ভুল নয় কারণ (0 & -0) == 00 টি দুটি পাওয়ার নয়। এটি বলার আরও ভাল উপায়

((n & -n) == n) যখন এন দুটি এর শক্তি বা দুটি বা শূন্যের শক্তির নেতিবাচক হয়।

যদি এন দুটি এর শক্তি হয়, তবে বাইনারিতে এন একক 1 পরে শূন্য হয়। দু'জনের পরিপূরকটি ইনভার্স +1 তাই বিট লাইন এভাবে আপ করা হয়

 n      0000100...000
-n      1111100...000
 n & -n 0000100...000

এই কাজটি দেখার জন্য, দু'টির পরিপূরককে বিপরীত +1 হিসাবে বিবেচনা করুন, -n == ~n + 1

n          0000100...000
inverse n  1111011...111
                     + 1
two's comp 1111100...000

যেহেতু আপনি দুটির পরিপূরক পেতে একটি যুক্ত করার সময় আপনি সমস্ত পথ দিয়ে যান।

যদি এন দুটি এর পাওয়ার ব্যতীত অন্য কিছু ছিল the তবে ফলাফলটি কিছুটা অনুপস্থিত হবে কারণ সেই বহনের কারণে দুটির পরিপূরককে সর্বোচ্চ বিট সেট করতে হবে না।

† - বা শূন্য বা দুটি শক্তির নেতিবাচক ... শীর্ষে বর্ণিত।


এবং সেখানে একটি কৌশল আছে যাতে কমপক্ষে উল্লেখযোগ্য 1 বিট বিচ্ছিন্ন করা যায়।
হট লিকস

4
হিসাবে হিসাবে (0 & -0) == 0, অবিলম্বে পূর্ববর্তী বিবৃতি হয় if (n <= 0) throw ...। অর্থাত পরীক্ষার অধীনে নম্বরটি কখনই 0 (বা নেতিবাচক) হবে না।
ব্যবহারকারী

4
@ মিশেল, ঠিক আছে। আমি শিরোনামে প্রশ্নের উত্তর দিচ্ছিলাম Random.javaযা আমি পড়িনি critic
মাইক স্যামুয়েল

4
@ মাইক, আমি বুঝতে পারি যে; যাইহোক, আমি মনে করি না কোডের মন্তব্যে বক্তব্যটি (যা প্রশ্নের মধ্যে অন্তর্ভুক্ত করা হয়েছে এবং শিরোনামে প্রশ্নের ভিত্তি হিসাবে) ঠিক তার আগে দাঁড়িয়ে যখন পূর্বের প্রতিষ্ঠিত পূর্বশর্ত প্রসঙ্গে দেখা যায় না। কোড এটি। আপনি যদি এখানে পোস্ট হিসাবে কেবল প্রশ্নটি দেখেন তবে আমরা কী ধরণের nতা সম্পর্কে কিছু জানি না ; আমি এই অনুমানটি পরীক্ষা করে দেখিনি, তবে কোনওরকম সন্দেহ রয়েছে যে একজন doubleএকইরকম আচরণ করবে।
ব্যবহারকারী

4
@ মিশেল, nএই প্রশ্নটির "জাভা" ট্যাগ থাকায় আমরা প্রকারের পক্ষে খুব ভাল সীমানা তৈরি করতে পারি । জাভা বা &তে সংজ্ঞায়িত করা হয় না । এটি কেবল পূর্ণসংখ্যার ধরণ এবং বুলিয়ানের উপর সংজ্ঞায়িত। যেহেতু বুলিয়ানদের জন্য সংজ্ঞায়িত করা হয়নি, তাই আমরা নিরাপদে নির্ধারণ করতে পারি অবিচ্ছেদ্য। doublefloat-n
মাইক স্যামুয়েল

95

কারণ 2 এর পরিপূরক, -nহয় ~n+1

যদি n2 এর শক্তি হয় তবে তার কেবলমাত্র একটি বিট সেট রয়েছে। সুতরাং ~nযে সমস্ত বিট সেট আছে এক ব্যতীত। 1 যোগ করুন এবং আপনি এটির n & (that thing)সমান হবে তা নিশ্চিত করে আবার বিশেষ বিট সেট করলেন n

কথোপকথনটিও সত্য কারণ 0 এবং negativeণাত্মক সংখ্যাগুলি সেই জাভা উত্সে পূর্ববর্তী লাইনের দ্বারা বাতিল করা হয়েছিল। যদি nএকাধিক বিট সেট থাকে তবে তার মধ্যে একটিতে সেরকম বিট। এই বিটটি সেট করা হবে না+1 কারণ এটি "শোষণ" করার জন্য একটি কম পরিষ্কার বিট রয়েছে:

 n: 00001001000
~n: 11110110111
-n: 11110111000  // the first 0 bit "absorbed" the +1
        ^
        |
        (n & -n) fails to equal n at this bit.

13

এটি সত্য কেন তা দেখতে আপনাকে বিটম্যাপ হিসাবে মানগুলি দেখতে হবে:

1 & 1 = 1
1 & 0 = 0
0 & 1 = 0
0 & 0 = 0

সুতরাং উভয় ক্ষেত্র 1 হলেই 1 টি বেরিয়ে আসবে।

এখন -n একটি 2 এর পরিপূরক করে। এটি সমস্ত পরিবর্তন 0করে 1এবং এটি 1 যুক্ত করে।

7 = 00000111
-1 = NEG(7) + 1 = 11111000 + 1 = 11111001

যাহোক

8 = 00001000
-8 = 11110111 + 1 = 11111000 

00001000  (8)
11111000  (-8)
--------- &
00001000 = 8.

কেবল 2 এর ক্ষমতার জন্য (n & -n)এন হবে।
এটি কারণ 2 এর একটি শক্তি শূন্যের দীর্ঘ সমুদ্রের একক সেট বিট হিসাবে উপস্থাপিত হয়। প্রত্যাখ্যান হুবহু বিপরীত, একক শূন্য (1 যেখানে ব্যবহৃত হত যেখানে 1 এর সমুদ্রে ) উত্পন্ন করবে । 1 যুক্ত করা নীচেরগুলি স্থানটি শূন্যে স্থানান্তরিত করবে।
এবং বিটওয়াইস এবং (&) আবার 1 টি ফিল্টার করবে।


8

দুটির পরিপূরক উপস্থাপনায়, দুটি পাওয়ার সম্পর্কে অনন্য বিষয় হ'ল এগুলি কাঁঠাল বিট ব্যতীত সমস্ত 0 বিট নিয়ে গঠিত যেখানে এন = 2 ^ কে:

base 2    base 10
000001 =  1 
000010 =  2
000100 =  4
     ...

দুটির পরিপূরকটিতে নেতিবাচক মান পেতে, আপনি সমস্ত বিটগুলি ফ্লিপ করুন এবং একটি যুক্ত করুন। দুটি শক্তির জন্য, এর অর্থ আপনি বাম দিকে 1s এর একগুচ্ছ পান এবং 1 বিট যা ইতিবাচক মানে ছিল এবং তার পরে ডানদিকে 0s এর গুচ্ছ পাবেন:

n   base 2  ~n      ~n+1 (-n)   n&-n  
1   000001  111110  111111      000001
2   000010  111101  111110      000010
4   000100  111011  111100      000100
8   001000  110111  111000      001000

আপনি সহজেই দেখতে পাবেন যে কলাম 2 এবং 4 এর ফলাফল কলাম 2 এর মতো হতে চলেছে।

আপনি যদি এই চার্টটি থেকে নিখোঁজ অন্যান্য মানগুলি দেখে থাকেন তবে আপনি দেখতে পাচ্ছেন যে এটি দুটির শক্তি ছাড়া কেন কিছুই ধরে রাখে না:

n   base 2  ~n      ~n+1 (-n)   n&-n  
1   000001  111110  111111      000001
2   000010  111101  111110      000010
3   000011  111100  111101      000001
4   000100  111011  111100      000100
5   000101  111010  111011      000001
6   000110  111001  111010      000010
7   000111  111000  111001      000001
8   001000  110111  111000      001000

n & -n (n> 0 এর জন্য) কেবলমাত্র 1 বিট সেট করবে এবং সেই বিটটি এন এর মধ্যে সর্বনিম্ন উল্লেখযোগ্য সেট বিট হবে। দুটি সংখ্যার ক্ষমতার জন্য সমস্ত সংখ্যার জন্য, সর্বনিম্ন উল্লেখযোগ্য সেট বিট হ'ল একমাত্র সেট বিট। অন্যান্য সমস্ত সংখ্যার জন্য, একাধিক বিট সেট রয়েছে, যার মধ্যে ফলাফলের মধ্যে কেবলমাত্র সবচেয়ে কম গুরুত্বপূর্ণ সেট করা হবে।


4

এটি 2 এর শক্তির সম্পত্তি এবং তাদের দুটি পরিপূরক

উদাহরণস্বরূপ, 8 নিন:

8  = 0b00001000

-8 = 0b11111000

দুটির পরিপূরক গণনা করা:

Starting:  0b00001000
Flip bits: 0b11110111  (one's complement)
Add one:   0b11111000  

AND 8    : 0b00001000

2 ক্ষমতা, শুধুমাত্র এক বিট সেট করা হবে যাতে যোগ এন কারণ হবে তম 2 বিট এন সেট হওয়ার (এক n যাও বহন রাখে তম বিট)। তারপরে আপনি যখন ANDদুটি নম্বর পাবেন, আপনি আসলটি ফিরে পাবেন।

2 এর সংখ্যা নয় এমন সংখ্যার জন্য, অন্যান্য বিটগুলি উল্টানো হবে না যাতে ANDআসল সংখ্যাটি পাওয়া যায় না।


4

সহজভাবে, যদি এন 2 এর শক্তি হয় তবে তার অর্থ একটি বিট 1 তে সেট করা হয় এবং অন্যগুলি 0 এর হয়:

00000...00001 = 2 ^ 0
00000...00010 = 2 ^ 1
00000...00100 = 2 ^ 2
00000...01000 = 2 ^ 3
00000...10000 = 2 ^ 4

and so on ...

এবং কারণ -nএটি একটি 2 এর পরিপূরক n(যার অর্থ একমাত্র বিট যা 1 টি রয়ে যায় যেমনটি থাকে এবং সেই বিটের বাম দিকে বিটগুলি 1 তে বসে থাকে যা আসলে অপরিহার্য নয় যেহেতু AND অপারেটরের ফলাফল &0 হবে যদি দুটি বিটের একটি শূন্য):

000000...000010000...00000 <<< n
&
111111...111110000...00000 <<< -n
--------------------------
000000...000010000...00000 <<< n

0

উদাহরণের মাধ্যমে দেখানো হয়েছে:

হেক্স = 0x000008 এ 8

হেক্স = 0xFFFFF8 এ -8

8 এবং -8 = 0x000008

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