बिटवाइज और मापांक ऑपरेटर के स्थान पर


90

हम जानते हैं कि उदाहरण के लिए दो की शक्ति के मोडुलो को इस तरह व्यक्त किया जा सकता है:

  x % 2 inpower n == x & (2 inpower n - 1).

उदाहरण:

x % 2 == x & 1
x % 4 == x & 3
x % 8 == x & 7 

दो संख्याओं की सामान्य शक्ति के बारे में क्या?

हम कहते हैं:

x% 7 ==?


8
@ नील - मोडुलो और बाइनरी और बहुत मौलिक संचालन हैं, मुझे लगता है कि वे किसी भी कंप्यूटर भाषा में उसी के बारे में हैं।
जेम्स कोलपेक

1
मैं पोस्ट की गई भाषा को न देखकर थोड़ा थक जाता हूं :) हालांकि मुझे लगता है कि आमतौर पर अगर वे निर्दिष्ट नहीं करते हैं, तो मुझे लगता है कि इसका मतलब है कि C ++ या C. मुझे आश्चर्य है कि यह कितना सच है ..
Garet Claborn

1
बस इसे समझने के लिए संघर्ष करने वाले, stackoverflow.com/a/13784820/1414639 पर एक नज़र डालें । ओह, और वी 8 के साथ जेएस में मुझे बिटवाइज़ ऑपरेटरों का उपयोग करके बहुत मामूली प्रदर्शन को बढ़ावा मिलता है ।
बर्डी हार्बरोव

1
@JamesKolpack एक बिटव्यू ऑपरेशन एक मॉडुलो की तुलना में सीपीयू पर तेजी से किया जा सकता है। वास्तव में, एक रजिस्टर को शून्य करने के लिए एक आम असेंबली ट्रिक इसे स्वयं के साथ XOR करना है (इस तथ्य के कारण)। आजकल एक कंपाइलर दो की शक्ति के एक मोडुलो को अनुकूलित करने में सक्षम हो सकता है, लेकिन मुझे नहीं पता
कैसर कीस्टर

जवाबों:


70

सबसे पहले, यह वास्तव में कहना सही नहीं है

x % 2 == x & 1

सरल प्रतिधारण x = -1:। जावा सहित कई भाषाओं में -1 % 2 == -1। यही है, %जरूरी नहीं कि मॉड्यूलर की पारंपरिक गणितीय परिभाषा है। उदाहरण के लिए, जावा इसे "शेष ऑपरेटर" कहता है।

बिटवाइज़ ऑप्टिमाइज़ेशन के संबंध में, केवल दो आसानी से मॉडुलो शक्तियों को बिटवाइज़ अंकगणित में किया जा सकता है। सामान्य शब्दों में, आधार के केवल सापेक्ष शक्तियों "आसानी से" आधार के साथ किया जा सकता है संख्या का प्रतिनिधित्व।

आधार 10 में, उदाहरण के लिए, गैर-नकारात्मक के लिए N, N mod 10^kबस कम से कम महत्वपूर्ण kअंक ले रहा है ।

संदर्भ


1
-1 = -1 (mod 2), सुनिश्चित नहीं हैं कि आप क्या प्राप्त कर रहे हैं - आपका मतलब यह IEEE 754 शेष के समान नहीं है ?
ब्लूराजा - डैनी पफ्लुगुफ्ट

2
@BlueRaja: mod 2 में -1 के लिए सामान्य अवशेष 1 en.wikipedia.org/wiki/Modular_arithmetic#Remainders
polygenel स्नेहक

@BlueRaja: यदि आप नकारात्मक संख्याओं की अनुमति देते हैं, तो आप मूल रूप से क्या सुनिश्चित कर सकते हैं (विशेषकर चूंकि कोई भाषा का उल्लेख नहीं किया गया था), वह है (a / b) / b + a % b == a, सी-टाइप ऑपरेटरों के लिए, एक और बी पूर्णांक, बी नॉनज़रो, और वह भी abs(a % b) < abs(b)एक ही प्रोविज़ोस के साथ।
डेविड थॉर्नले

1
@DavidThornley - मान लीजिए आपका मतलब है (a / b)* b + a % b == a
1934

40

बिटवाइज़ का उपयोग करके 2 ^ i नंबरों के मोडुलो को खोजने का केवल एक सरल तरीका है।

N के 3, n% 7 जैसे लिंक के अनुसार Mersenne मामलों को हल करने का एक सरल तरीका है ... n% 5 के लिए विशेष मामले हैं, n% 255, और समग्र मामले जैसे n% 6।

मामलों के लिए 2 ^ i, (2, 4, 8, 16 ...)

n % 2^i = n & (2^i - 1)

अधिक जटिल लोगों को समझाना कठिन है। बहुत उत्सुक होने पर ही पढ़ें।


1
वोट ++; उत्कृष्ट लिंक, संदर्भ के लिए धन्यवाद। मैं दूसरों को देख लेने की सलाह देता हूं, यह पढ़ने के लायक है, भले ही यह थोड़ा जटिल हो।
varzeak

लिंक उत्तर का सबसे अच्छा हिस्सा है।
अमित कुमार

n% 2 ^ i = n & (1 << i - 1)
कार्तिक सिंह

18

यह केवल दो (और अक्सर केवल सकारात्मक वाले) की शक्तियों के लिए काम करता है क्योंकि उनके पास अपने द्विआधारी प्रतिनिधित्व में केवल एक बिट '1' पर सेट होने की अनूठी संपत्ति है। क्योंकि संख्याओं का कोई अन्य वर्ग इस संपत्ति को साझा नहीं करता है, इसलिए आप अधिकांश मापांक अभिव्यक्तियों के लिए बिटवाइज़-और भाव नहीं बना सकते हैं।


2
यदि आप एक टर्नरी वास्तुकला पर काम कर रहे हैं, तो इससे चीजें थोड़ी बदल जाती हैं ... लेकिन संभावना शून्य के बारे में है।
नोल्डोरिन

मुझे पसंद है कि आप इसे कैसे फिर से तैयार कर रहे हैं: "जो चीजों को थोड़ा बदल देता है "
j314159265658989323238

12

यह विशेष रूप से एक विशेष मामला है क्योंकि कंप्यूटर आधार 2 में संख्याओं का प्रतिनिधित्व करते हैं। यह सामान्य है:

(संख्या) आधार % बेस x

(संख्या) आधार के अंतिम x अंकों के बराबर है ।


5

2 की शक्तियों के अलावा मोडुली हैं जिनके लिए कुशल एल्गोरिदम मौजूद हैं।

उदाहरण के लिए, यदि x 32 बिट्स अहस्ताक्षरित int है तो x% 3 = popcnt (x & 0x55555555) - popcnt (x & 0xaaaaaaaa)


4

मोडुलो "7" बिना "%" ऑपरेटर के

int a = x % 7;

int a = (x + x / 7) & 7;

3
10% 2 = 0. (10 + 10/2) और 2 = 15 और 2 = 2 के लिए काम नहीं करता है, इसी तरह 10% 6 = 4. (10 + 10/6) और 6 = 11 और 6 = 2
श्रीराम मुरली

10
इसके अलावा, आप मॉडुलो का उपयोग करने से बचना चाहते हैं तो आप क्यों बांटना चाहेंगे? AFAIK, विभाजित करने का निर्देश शेष प्राप्त करने के लिए एक ही है।
हॉर्स स्मीथ

1
@ श्रीराममुरली थॉट्स क्योंकि आपने एक मॉड का भी इस्तेमाल किया था, बेशक यह काम नहीं करेगा, यह ओपी ने कहा कि यह अजीब के लिए एक वर्कअराउंड है ।
ylun.ca

3

&बाइनरी में बिटवाइज़-और ( ) ऑपरेटर का उपयोग नहीं करना है। सबूत के स्केच:

मान लीजिए कि इस तरह के एक मूल्य k थे x & k == x % (k + 1), लेकिन k! = 2 ^ n - 1 । तब यदि x == k , तो अभिव्यक्ति x & k"सही ढंग से संचालित" होती है और परिणाम k है । अब, x == ki पर विचार करें : यदि k में कोई "0" बिट्स थे , तो कुछ i 0 से अधिक हैं, जो कि ki केवल उन स्थितियों में 1-बिट्स के साथ व्यक्त किए जा सकते हैं। (जैसे, १०११ (११) ०१११ (100) हो जाना चाहिए जब १०० (४) इससे घटाया गया हो, इस स्थिति में ००० बिट १०० हो जाता है जब मैं = ४। ) यदि k की अभिव्यक्ति से थोड़ा सा शून्य से बदलना होगा। एक से एक का प्रतिनिधित्व करने के लिए की, तो यह सही ढंग से गणना नहीं कर सकताx% (k + 1) , जो इस मामले में ki होना चाहिए , लेकिन बिटवाइज़ बूलियन के लिए और मास्क को दिए गए मान का उत्पादन करने का कोई तरीका नहीं है।


2

इस विशिष्ट मामले में (मॉड 7), हम अभी भी बिटवाइज ऑपरेटरों के साथ% 7 को बदल सकते हैं:

// Return X%7 for X >= 0.
int mod7(int x)
{
  while (x > 7) x = (x&7) + (x>>3);
  return (x == 7)?0:x;
}

यह काम करता है क्योंकि 8% 7 = 1. जाहिर है, यह कोड शायद एक साधारण एक्स% 7 की तुलना में कम कुशल है, और निश्चित रूप से कम पठनीय है।


1

बिटवाइज़_एंड, बिटवाइज़_ओर, और बिटवाइज़_नॉट का उपयोग करके आप किसी भी बिट कॉन्फ़िगरेशन को दूसरे बिट कॉन्फ़िगरेशन (यानी इन ऑपरेटरों के सेट "कार्यात्मक रूप से पूर्ण" हैं) को संशोधित कर सकते हैं। हालांकि, मापांक जैसे ऑपरेशन के लिए, सामान्य सूत्र आवश्यक रूप से काफी जटिल होगा, मैं इसे फिर से बनाने की कोशिश भी नहीं करूंगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.