यदि कोई दी गई संख्या C या विषम है तो मैं कैसे जांच सकता हूं?
यदि कोई दी गई संख्या C या विषम है तो मैं कैसे जांच सकता हूं?
जवाबों:
2 से भाग देने पर शेष रहने पर जाँचने के लिए मोडुलो (%) ऑपरेटर का उपयोग करें:
if (x % 2) { /* x is odd */ }
कुछ लोगों ने ऊपर दिए गए मेरे उत्तर की आलोचना करते हुए कहा कि x & 1 का उपयोग करना "तेज़" या "अधिक कुशल" है। मैं इस मामले को नहीं मानता।
जिज्ञासा से बाहर, मैंने दो तुच्छ परीक्षण केस प्रोग्राम बनाए:
/* modulo.c */
#include <stdio.h>
int main(void)
{
int x;
for (x = 0; x < 10; x++)
if (x % 2)
printf("%d is odd\n", x);
return 0;
}
/* and.c */
#include <stdio.h>
int main(void)
{
int x;
for (x = 0; x < 10; x++)
if (x & 1)
printf("%d is odd\n", x);
return 0;
}
मैंने तब अपने एक मशीन 5 अलग-अलग समय पर 4.1.3 के साथ इन्हें संकलित किया:
मैंने प्रत्येक कंपाइल के असेंबली आउटपुट (gcc -S का उपयोग करके) की जांच की और पाया कि प्रत्येक मामले में, and.c और modulo.c के लिए आउटपुट समान थे (वे दोनों .l $ 1 का उपयोग करते थे,% eax निर्देश)। मुझे संदेह है कि यह एक "नया" फीचर है, और मुझे संदेह है कि यह प्राचीन संस्करणों में वापस आता है। मैं किसी भी आधुनिक (पिछले 20 वर्षों में किए गए) गैर-अभिलेखीय संकलक, वाणिज्यिक या खुले स्रोत पर संदेह करता हूं, इस तरह के अनुकूलन का अभाव है। मैं अन्य संकलक पर परीक्षण करूंगा, लेकिन मेरे पास फिलहाल उपलब्ध नहीं है।
अगर कोई अन्य संकलक और / या प्लेटफ़ॉर्म लक्ष्य का परीक्षण करने के लिए परवाह करेगा, और एक अलग परिणाम प्राप्त करेगा, तो मुझे जानने में बहुत दिलचस्पी होगी।
अंत में, मोडुलो संस्करण मानक द्वारा कार्य करने के लिए गारंटीकृत है कि पूर्णांक पूर्णांक के कार्यान्वयन के प्रतिनिधित्व के बावजूद पूर्णांक सकारात्मक, नकारात्मक या शून्य है या नहीं। बिटवाइज़-वर्जन नहीं है। हां, मुझे एहसास है कि दो का पूरक कुछ सर्वव्यापी है, इसलिए यह वास्तव में कोई मुद्दा नहीं है।
आप लोग बहुत ही कुशल हैं। आप वास्तव में क्या चाहते हैं:
public boolean isOdd(int num) {
int i = 0;
boolean odd = false;
while (i != num) {
odd = !odd;
i = i + 1;
}
return odd;
}
के लिए दोहराएं isEven
।
बेशक, यह नकारात्मक संख्या के लिए काम नहीं करता है। लेकिन प्रतिभा के साथ बलिदान आता है ...
बिट अंकगणित का प्रयोग करें:
if((x & 1) == 0)
printf("EVEN!\n");
else
printf("ODD!\n");
यह विभाजन या मापांक का उपयोग करने से तेज है।
[मजाक मोड = "पर"]
public enum Evenness
{
Unknown = 0,
Even = 1,
Odd = 2
}
public static Evenness AnalyzeEvenness(object o)
{
if (o == null)
return Evenness.Unknown;
string foo = o.ToString();
if (String.IsNullOrEmpty(foo))
return Evenness.Unknown;
char bar = foo[foo.Length - 1];
switch (bar)
{
case '0':
case '2':
case '4':
case '6':
case '8':
return Evenness.Even;
case '1':
case '3':
case '5':
case '7':
case '9':
return Evenness.Odd;
default:
return Evenness.Unknown;
}
}
[मजाक मोड = "बंद"]
संपादित करें: एनम को भ्रमित करने वाले मूल्य जोड़े।
Ffpf के जवाब में - मेरे पास एक सहकर्मी के साथ वर्षों पहले ठीक यही तर्क था, और जवाब नहीं है , यह नकारात्मक संख्याओं के साथ काम नहीं करता है।
सी मानक यह निर्धारित करता है कि नकारात्मक संख्या को 3 तरीकों से दर्शाया जा सकता है:
इस तरह की जाँच:
isEven = (x & 1);
2 के पूरक और संकेत और परिमाण प्रतिनिधित्व के लिए काम करेंगे, लेकिन 1 के पूरक के लिए नहीं।
हालाँकि, मेरा मानना है कि निम्नलिखित सभी मामलों के लिए काम करेगा:
isEven = (x & 1) ^ ((-1 & 1) | ((x < 0) ? 0 : 1)));
यह इंगित करने के लिए ffpf के लिए धन्यवाद कि पाठ बॉक्स मेरे चरित्र से कम के बाद सब कुछ खा रहा था!
एक अच्छा है:
/*forward declaration, C compiles in one pass*/
bool isOdd(unsigned int n);
bool isEven(unsigned int n)
{
if (n == 0)
return true ; // I know 0 is even
else
return isOdd(n-1) ; // n is even if n-1 is odd
}
bool isOdd(unsigned int n)
{
if (n == 0)
return false ;
else
return isEven(n-1) ; // n is odd if n-1 is even
}
ध्यान दें कि यह विधि दो कार्यों को शामिल करने के लिए पूंछ की पुनरावृत्ति का उपयोग करती है। यदि आपका कंपाइलर स्कीम संकलक की तरह पूंछ पुनरावृत्ति का समर्थन करता है तो इसे कुशलता से लागू किया जा सकता है। इस मामले में स्टैक ओवरफ्लो नहीं होना चाहिए!
एक संख्या और भी है, जब दो से विभाजित किया जाता है, तो शेष 0. 0. एक संख्या विषम होती है, जब 2 से विभाजित किया जाता है, तो शेष 1 होता है।
// Java
public static boolean isOdd(int num){
return num % 2 != 0;
}
/* C */
int isOdd(int num){
return num % 2;
}
तरीके बहुत अच्छे हैं!
i % 2 == 0
मैं कहूंगा कि इसे 2 से विभाजित करें और यदि कोई 0 शेष है, तो भी, अन्यथा यह विषम है।
मापांक (%) का उपयोग यह आसान बनाता है।
जैसे। 4% 2 = 0 इसलिए 4 भी 5% 2 = 1 है इसलिए 5 विषम है
समस्या का एक और समाधान
(बच्चों को वोट देने के लिए स्वागत है)
bool isEven(unsigned int x)
{
unsigned int half1 = 0, half2 = 0;
while (x)
{
if (x) { half1++; x--; }
if (x) { half2++; x--; }
}
return half1 == half2;
}
मैं पूर्णांकों की तालिका (0 भले ही 1 विषम हो) का निर्माण करूँगा (ताकि कोई लुकअप कर सके: D), लेकिन gcc मुझे इस तरह के आकारों के सरणियाँ नहीं बनाने देगा:
typedef unsigned int uint;
char parity_uint [UINT_MAX];
char parity_sint_shifted [((uint) INT_MAX) + ((uint) abs (INT_MIN))];
char* parity_sint = parity_sint_shifted - INT_MIN;
void build_parity_tables () {
char parity = 0;
unsigned int ui;
for (ui = 1; ui <= UINT_MAX; ++ui) {
parity_uint [ui - 1] = parity;
parity = !parity;
}
parity = 0;
int si;
for (si = 1; si <= INT_MAX; ++si) {
parity_sint [si - 1] = parity;
parity = !parity;
}
parity = 1;
for (si = -1; si >= INT_MIN; --si) {
parity_sint [si] = parity;
parity = !parity;
}
}
char uparity (unsigned int n) {
if (n == 0) {
return 0;
}
return parity_uint [n - 1];
}
char sparity (int n) {
if (n == 0) {
return 0;
}
if (n < 0) {
++n;
}
return parity_sint [n - 1];
}
तो चलिए इसके बजाय और भी विषम की गणितीय परिभाषा का सहारा लेते हैं।
एक पूर्णांक n तब भी होता है जब पूर्णांक k मौजूद होता है जैसे कि n = 2k।
एक पूर्णांक n विषम है यदि कोई पूर्णांक k मौजूद है जैसे कि n = 2k + 1।
यहाँ इसके लिए कोड है:
char even (int n) {
int k;
for (k = INT_MIN; k <= INT_MAX; ++k) {
if (n == 2 * k) {
return 1;
}
}
return 0;
}
char odd (int n) {
int k;
for (k = INT_MIN; k <= INT_MAX; ++k) {
if (n == 2 * k + 1) {
return 1;
}
}
return 0;
}
बता दें कि C- पूर्णांक int
किसी दिए गए C संकलन में संभावित मानों को दर्शाते हैं । (ध्यान दें कि C- पूर्णांक पूर्णांकों का सबसेट है।)
अब किसी को यह चिंता हो सकती है कि सी-पूर्णांक में दिए गए n के लिए कि संबंधित पूर्णांक k, C- पूर्णांक के भीतर मौजूद नहीं हो सकता है। लेकिन थोड़े प्रमाण के साथ यह दिखाया जा सकता है कि सभी पूर्णांकों के लिए n; | n | <= | 2 एन | (*), जहाँ | n | "n यदि n धनात्मक और n पर अन्यथा है"। दूसरे शब्दों में, पूर्णांक में सभी n के लिए निम्न में से कम से कम एक (वास्तव में मामले (1 और 2) या मामले (3 और 4) हैं, लेकिन मैं इसे यहाँ साबित नहीं करूँगा):
केस 1: एन <= 2 एन।
केस 2: -एन <= -2 एन।
केस 3: -एन <= 2 एन।
केस 4: एन <= -2 एन।
अब 2k = n लें। (ऐसा ak मौजूद है अगर n सम है, लेकिन मैं इसे यहाँ सिद्ध नहीं करूँगा। यदि n भी नहीं है, तो लूप even
वैसे भी जल्दी वापस आने में विफल रहता है, इसलिए यह कोई फर्क नहीं पड़ता।) लेकिन इसका अर्थ है कि <n नहीं 0 द्वारा (*) और तथ्य (फिर से यहाँ साबित नहीं) कि सभी मीटर के लिए, पूर्णांक 2 में z = z का अर्थ है कि m m के बराबर z नहीं है 0. नहीं है। मामले में n 0, 2 * 0 = 0 है। इसलिए 0 भी हो गया है (यदि n = 0 है तो 0 C-पूर्णांकों में है क्योंकि n फ़ंक्शन में C-पूर्णांक में है even
, इसलिए k = 0 C-पूर्णांक में है)। इस तरह के सी में पूर्णांक एन में सी-पूर्णांक में एन के लिए मौजूद है अगर एन भी है।
इसी तरह के तर्क से पता चलता है कि यदि n विषम है, तो C-पूर्णांकों में ak मौजूद है जैसे कि n = 2k + 1।
इसलिए यहां प्रस्तुत even
और odd
प्रस्तुत सभी सी-पूर्णांक के लिए ठीक से काम करेंगे।
i % 2
बहुत छोटा है और शायद अधिक कुशल है।
%2
सभी पूर्णांकों के लिए काम करता है।
// C#
bool isEven = ((i % 2) == 0);
typedef
या #define
या कुछ और।
यहाँ जावा में एक उत्तर है:
public static boolean isEven (Integer Number) {
Pattern number = Pattern.compile("^.*?(?:[02]|8|(?:6|4))$");
String num = Number.toString(Number);
Boolean numbr = new Boolean(number.matcher(num).matches());
return numbr.booleanValue();
}
इसे इस्तेमाल करे: return (((a>>1)<<1) == a)
उदाहरण:
a = 10101011
-----------------
a>>1 --> 01010101
a<<1 --> 10101010
b = 10011100
-----------------
b>>1 --> 01001110
b<<1 --> 10011100
इस मनोरंजक चर्चा को पढ़ते हुए, मुझे याद आया कि मेरे पास एक वास्तविक-दुनिया, समय-संवेदनशील कार्य है जो मुख्य लूप के अंदर विषम और यहां तक कि संख्याओं के लिए परीक्षण किया गया था। यह एक पूर्णांक पावर फ़ंक्शन है, जो StackOverflow पर अन्यत्र पोस्ट किया गया है, जो निम्नानुसार है। बेंचमार्क काफी आश्चर्यजनक थे। कम से कम इस वास्तविक दुनिया के समारोह में, मोडुलो धीमा है , और काफी ऐसा है। विजेता, एक व्यापक अंतर से, modulo के 67% समय की आवश्यकता होती है, एक या (!) दृष्टिकोण है , और इस पृष्ठ पर कहीं और नहीं पाया जा सकता है।
static dbl IntPow(dbl st0, int x) {
UINT OrMask = UINT_MAX -1;
dbl st1=1.0;
if(0==x) return (dbl)1.0;
while(1 != x) {
if (UINT_MAX == (x|OrMask)) { // if LSB is 1...
//if(x & 1) {
//if(x % 2) {
st1 *= st0;
}
x = x >> 1; // shift x right 1 bit...
st0 *= st0;
}
return st1 * st0;
}
300 मिलियन छोरों के लिए, बेंचमार्क समय इस प्रकार हैं।
3.962 | और मुखौटा दृष्टिकोण
4.851 और दृष्टिकोण
5.850% दृष्टिकोण
सिद्धांत या असेंबली लैंग्वेज लिस्टिंग के बारे में सोचने वाले लोगों के लिए, इस तरह की दलीलें बैठती हैं, यह एक सतर्क कहानी होनी चाहिए। स्वर्ग और पृथ्वी में अधिक चीजें हैं, होराटियो, आपके दर्शन में सपने की तुलना में हैं।
unsigned x
रूप x = x >> 1;
में उपयोग करने के लिए बेहतर है जब x < 0
। अस्पष्ट क्यों x
और OrMask
प्रकार में भिन्न। एक while(x)
परीक्षण का उपयोग कर फिर से लिखने के लिए पर्याप्त सरल है ।
% 2
बिटवाइज़ का उपयोग करके मामले को संकलित करने के लिए पर्याप्त स्मार्ट होना चाहिए &
। मैंने अभी इसका परीक्षण किया है और परिणाम पूरी तरह से समान हैं (वीएस2015, रिलीज सभी अनुकूलन के साथ बनाता है, दोनों x86 और x64)। स्वीकृत उत्तर में यह जीसीसी (2008 में लिखित) के लिए भी लिखा गया है।
or
तुलना में किसी भी तेजी से and
होने की संभावना नहीं है। यहां तक कि अगर इस तरह के एक अजीब मंच / कंपाइलर कॉम्बो था (और आपने न तो पोस्ट किया है और न ही बेंचमार्क का उपयोग करने के लिए कोड का उपयोग किया है), अन्य कंपाइलरों के आधार पर उसी के अनुरूप व्यवहार करने के लिए एक खराब अनुकूलन शर्त होगी। इसलिए, जैसा कि मैंने लिखा है, मुझे आश्चर्य है कि यह किस प्लेटफॉर्म / कंपाइलर पर परीक्षण किया गया था , क्योंकि मैं लगभग निश्चित हूं कि इसे सही तरीके से नहीं मापा गया था।
यह उनके उत्तर के संबंध में @RocketRoy के साथ चर्चा करने के लिए अनुवर्ती है , लेकिन यह उन लोगों के लिए उपयोगी हो सकता है जो इन परिणामों की तुलना करना चाहते हैं।
tl; dr जो मैंने देखा है, उससे रॉय का दृष्टिकोण ( (0xFFFFFFFF == (x | 0xFFFFFFFE)
) पूरी तरह x & 1
से mod
दृष्टिकोण के रूप में अनुकूलित नहीं है , लेकिन व्यवहार में चलने वाले समय को सभी मामलों में बराबर होना चाहिए।
इसलिए, पहले मैंने कंपाइलर एक्सप्लोरर का उपयोग करके संकलित आउटपुट की तुलना की :
परीक्षण किए गए कार्य:
int isOdd_mod(unsigned x) {
return (x % 2);
}
int isOdd_and(unsigned x) {
return (x & 1);
}
int isOdd_or(unsigned x) {
return (0xFFFFFFFF == (x | 0xFFFFFFFE));
}
CLO 3.9.0 -O3 के साथ:
isOdd_mod(unsigned int): # @isOdd_mod(unsigned int)
and edi, 1
mov eax, edi
ret
isOdd_and(unsigned int): # @isOdd_and(unsigned int)
and edi, 1
mov eax, edi
ret
isOdd_or(unsigned int): # @isOdd_or(unsigned int)
and edi, 1
mov eax, edi
ret
GCC 6.2 -O3 के साथ:
isOdd_mod(unsigned int):
mov eax, edi
and eax, 1
ret
isOdd_and(unsigned int):
mov eax, edi
and eax, 1
ret
isOdd_or(unsigned int):
or edi, -2
xor eax, eax
cmp edi, -1
sete al
ret
सलाम क्लैंग के लिए, यह महसूस किया कि सभी तीन मामले कार्यात्मक रूप से बराबर हैं। हालाँकि, रॉय का दृष्टिकोण GCC में अनुकूलित नहीं है, इसलिए YMMV।
यह विज़ुअल स्टूडियो के साथ समान है; इन तीन फ़ंक्शंस के लिए डिस्सैम्फ़र रिलीज़ x64 (VS2015) का निरीक्षण करते हुए, मैं देख सकता था कि तुलना भाग "मॉड" और "और" मामलों के लिए बराबर है, और रॉय के "या" केस के लिए थोड़ा बड़ा है:
// x % 2
test bl,1
je (some address)
// x & 1
test bl,1
je (some address)
// Roy's bitwise or
mov eax,ebx
or eax,0FFFFFFFEh
cmp eax,0FFFFFFFFh
jne (some address)
हालाँकि, इन तीन विकल्पों (सादे मॉड, बिटवाइज़ या बिटवाइज़ और) की तुलना करने के लिए एक वास्तविक बेंचमार्क चलाने के बाद, परिणाम पूरी तरह से बराबर थे (फिर से, विजुअल स्टूडियो 2005 x86 / x64, रिलीज़ बिल्ड, कोई डीबगर संलग्न नहीं)।
रिलीज़ असेंबली test
निर्देश and
और mod
मामलों का उपयोग करती है, जबकि रॉय का केस उपयोग करता हैcmp eax,0FFFFFFFFh
दृष्टिकोण , लेकिन यह बहुत अधिक अनियंत्रित और अनुकूलित है, इसलिए व्यवहार में कोई अंतर नहीं है।
20 रन (i7 3610QM, विंडोज 10 पावर प्लान टू हाई परफॉर्मेंस) के बाद मेरे परिणाम:
[टेस्ट: प्लेन मॉड 2] एवरेज टाइम: ६9 ९ .२ ९ एमएस (सापेक्ष भिन्नता: + ०.०००%) [टेस्ट: बिटवाइज़ या] एवरेज टाइम: 689.63 एमएस (सापेक्ष अंतर।: + 0.048%) [टेस्ट: बिटवाइज़ और] एवरेज टाइम: 687.80 एमएस (सापेक्ष भिन्नता: -0.217%)
इन विकल्पों के बीच अंतर 0.3% से कम है, इसलिए यह स्पष्ट है कि विधानसभा सभी मामलों में समान है।
यहां वह कोड है यदि कोई भी कोशिश करना चाहता है, एक चेतावनी के साथ कि मैंने केवल इसे विंडोज पर परीक्षण किया है ( परिभाषा के #if LINUX
लिए सशर्त की जांच करें get_time
और यदि आवश्यक हो तो इसे लागू करें, इस उत्तर से लिया गया है )।
#include <stdio.h>
#if LINUX
#include <sys/time.h>
#include <sys/resource.h>
double get_time()
{
struct timeval t;
struct timezone tzp;
gettimeofday(&t, &tzp);
return t.tv_sec + t.tv_usec*1e-6;
}
#else
#include <windows.h>
double get_time()
{
LARGE_INTEGER t, f;
QueryPerformanceCounter(&t);
QueryPerformanceFrequency(&f);
return (double)t.QuadPart / (double)f.QuadPart * 1000.0;
}
#endif
#define NUM_ITERATIONS (1000 * 1000 * 1000)
// using a macro to avoid function call overhead
#define Benchmark(accumulator, name, operation) { \
double startTime = get_time(); \
double dummySum = 0.0, elapsed; \
int x; \
for (x = 0; x < NUM_ITERATIONS; x++) { \
if (operation) dummySum += x; \
} \
elapsed = get_time() - startTime; \
accumulator += elapsed; \
if (dummySum > 2000) \
printf("[Test: %-12s] %0.2f ms\r\n", name, elapsed); \
}
void DumpAverage(char *test, double totalTime, double reference)
{
printf("[Test: %-12s] AVERAGE TIME: %0.2f ms (Relative diff.: %+6.3f%%)\r\n",
test, totalTime, (totalTime - reference) / reference * 100.0);
}
int main(void)
{
int repeats = 20;
double runningTimes[3] = { 0 };
int k;
for (k = 0; k < repeats; k++) {
printf("Run %d of %d...\r\n", k + 1, repeats);
Benchmark(runningTimes[0], "Plain mod 2", (x % 2));
Benchmark(runningTimes[1], "Bitwise or", (0xFFFFFFFF == (x | 0xFFFFFFFE)));
Benchmark(runningTimes[2], "Bitwise and", (x & 1));
}
{
double reference = runningTimes[0] / repeats;
printf("\r\n");
DumpAverage("Plain mod 2", runningTimes[0] / repeats, reference);
DumpAverage("Bitwise or", runningTimes[1] / repeats, reference);
DumpAverage("Bitwise and", runningTimes[2] / repeats, reference);
}
getchar();
return 0;
}
मुझे पता है कि यह सिर्फ सिंथेटिक चीनी है और केवल .net में लागू है, लेकिन विस्तार विधि के बारे में क्या ...
public static class RudiGroblerExtensions
{
public static bool IsOdd(this int i)
{
return ((i % 2) != 0);
}
}
अब आप निम्न कार्य कर सकते हैं
int i = 5;
if (i.IsOdd())
{
// Do something...
}
"रचनात्मक लेकिन भ्रामक श्रेणी" में मैं प्रदान करता हूं:
int isOdd(int n) { return n ^ n * n ? isOdd(n * n) : n; }
इस विषय पर एक संस्करण जो Microsoft C ++ के लिए विशिष्ट है:
__declspec(naked) bool __fastcall isOdd(const int x)
{
__asm
{
mov eax,ecx
mul eax
mul eax
mul eax
mul eax
mul eax
mul eax
ret
}
}
बिटवाइज विधि पूर्णांक के आंतरिक प्रतिनिधित्व पर निर्भर करती है। मोडुलो कहीं भी काम करेगा एक मोडुलो ऑपरेटर है। उदाहरण के लिए, कुछ सिस्टम वास्तव में टैगिंग के लिए निम्न स्तर की बिट्स का उपयोग करते हैं (जैसे गतिशील भाषाएं), इसलिए कच्चा x & 1 वास्तव में उस स्थिति में काम नहीं करेगा।
IsOdd (int x) {सही लौटा; }
शुद्धता का प्रमाण - सभी सकारात्मक पूर्णांकों के सेट पर विचार करें और मान लें कि पूर्णांक का एक गैर-खाली सेट है जो विषम नहीं है। क्योंकि धनात्मक पूर्णांक अच्छी तरह से क्रमबद्ध हैं, एक छोटी संख्या विषम संख्या नहीं होगी, जो अपने आप में बहुत विषम है, इसलिए स्पष्ट रूप से यह संख्या सेट में नहीं हो सकती है। इसलिए यह सेट गैर-रिक्त नहीं हो सकता है। ऋणात्मक पूर्णांकों के लिए दोहराएं, न कि सबसे बड़ी विषम संख्या को देखने के लिए।
जैसा कि कुछ लोगों ने पोस्ट किया है, ऐसा करने के कई तरीके हैं। इस वेबसाइट के अनुसार , सबसे तेज़ तरीका मापांक ऑपरेटर है:
if (x % 2 == 0)
total += 1; //even number
else
total -= 1; //odd number
हालाँकि, यहाँ कुछ अन्य कोड है जो लेखक द्वारा चिह्नित किए गए थे जो ऊपर दिए गए सामान्य मापांक ऑपरेशन की तुलना में धीमी गति से चलते थे:
if ((x & 1) == 0)
total += 1; //even number
else
total -= 1; //odd number
System.Math.DivRem((long)x, (long)2, out outvalue);
if ( outvalue == 0)
total += 1; //even number
else
total -= 1; //odd number
if (((x / 2) * 2) == x)
total += 1; //even number
else
total -= 1; //odd number
if (((x >> 1) << 1) == x)
total += 1; //even number
else
total -= 1; //odd number
while (index > 1)
index -= 2;
if (index == 0)
total += 1; //even number
else
total -= 1; //odd number
tempstr = x.ToString();
index = tempstr.Length - 1;
//this assumes base 10
if (tempstr[index] == '0' || tempstr[index] == '2' || tempstr[index] == '4' || tempstr[index] == '6' || tempstr[index] == '8')
total += 1; //even number
else
total -= 1; //odd number
कितने लोगों को भी Math.System.DivRem विधि का पता था या वे इसका उपयोग क्यों करेंगे ??
हममें से उन लोगों के लिए बिटवाइन ऑपरेटर पद्धति पर अधिक विस्तार देने के लिए जिन्होंने हमारी पढ़ाई के दौरान बूलियन बीजगणित नहीं किया था, यहाँ एक स्पष्टीकरण है। संभवतः ओपी के लिए बहुत अधिक उपयोग नहीं है, लेकिन मुझे यह स्पष्ट करना पसंद है कि NUMBER और 1 क्यों काम करता है।
कृपया ध्यान दें कि जैसे किसी ने उत्तर दिया है, जिस तरह से नकारात्मक संख्याओं का प्रतिनिधित्व किया जाता है वह इस पद्धति को काम करने से रोक सकता है। वास्तव में यह मॉडुलो ऑपरेटर विधि को भी तोड़ सकता है क्योंकि प्रत्येक भाषा इस बात से भिन्न हो सकती है कि यह नकारात्मक ऑपरेंड से कैसे निपटती है।
हालाँकि यदि आप जानते हैं कि NUMBER हमेशा सकारात्मक रहेगा, तो यह अच्छी तरह से काम करता है।
जैसा कि ऊपर दिए गए टूनी ने यह बिंदु बनाया कि बाइनरी (और इनकार) में केवल अंतिम अंक महत्वपूर्ण है।
एक बूलियन लॉजिक और गेट यह बताता है कि दोनों इनपुट्स को वापस करने के लिए 1 (या हाई वोल्टेज) होना चाहिए।
1 & 0 = 0।
0 और 1 = 0।
0 & 0 = 0।
1 & 1 = 1।
यदि आप बाइनरी के रूप में किसी भी संख्या का प्रतिनिधित्व करते हैं (मैंने यहां 8 बिट प्रतिनिधित्व का उपयोग किया है), विषम संख्याओं में अंत में 1 है, यहां तक कि संख्याओं में 0 भी है।
उदाहरण के लिए:
1 = 00000001
2 = 00000010
3 = 00000011
4 = 00000100
यदि आप कोई संख्या लेते हैं और बिटवाइस (और जावा में) का उपयोग करते हैं तो यह या तो 00000001 लौटा देगा, = 1 का अर्थ है कि संख्या विषम है। OR 00000000 = 0, अर्थात संख्या सम है।
उदाहरण के लिए
अजीब है?
1 & 1 =
00000001 और
00000001 =
00000001 <- विषम
2 और 1 =
00000010 और
00000001 =
00000000 <- यहां तक कि
54 और 1 =
00000001 और
00110110 =
00000000 <- यहां तक कि
यही कारण है कि यह काम करता है:
if(number & 1){
//Number is odd
} else {
//Number is even
}
क्षमा करें यदि यह बेमानी है।
संख्या शून्य समानता | शून्य http://tinyurl.com/oexhr3k
पायथन कोड अनुक्रम।
# defining function for number parity check
def parity(number):
"""Parity check function"""
# if number is 0 (zero) return 'Zero neither ODD nor EVEN',
# otherwise number&1, checking last bit, if 0, then EVEN,
# if 1, then ODD.
return (number == 0 and 'Zero neither ODD nor EVEN') \
or (number&1 and 'ODD' or 'EVEN')
# cycle trough numbers from 0 to 13
for number in range(0, 14):
print "{0:>4} : {0:08b} : {1:}".format(number, parity(number))
आउटपुट:
0 : 00000000 : Zero neither ODD nor EVEN
1 : 00000001 : ODD
2 : 00000010 : EVEN
3 : 00000011 : ODD
4 : 00000100 : EVEN
5 : 00000101 : ODD
6 : 00000110 : EVEN
7 : 00000111 : ODD
8 : 00001000 : EVEN
9 : 00001001 : ODD
10 : 00001010 : EVEN
11 : 00001011 : ODD
12 : 00001100 : EVEN
13 : 00001101 : ODD
चर्चा के लिए ...
आपको केवल किसी भी संख्या में अंतिम अंक देखने की आवश्यकता है, यह देखने के लिए कि क्या यह सम विषम है या नहीं। हस्ताक्षरित, अहस्ताक्षरित, सकारात्मक, नकारात्मक - वे इस संबंध में सभी समान हैं। तो यह सभी दौर में काम करना चाहिए: -
void tellMeIfItIsAnOddNumberPlease(int iToTest){
int iLastDigit;
iLastDigit = iToTest - (iToTest / 10 * 10);
if (iLastDigit % 2 == 0){
printf("The number %d is even!\n", iToTest);
} else {
printf("The number %d is odd!\n", iToTest);
}
}
यहां कुंजी कोड की तीसरी पंक्ति में है, डिवीजन ऑपरेटर एक पूर्णांक विभाजन करता है, जिससे परिणाम परिणाम का आंशिक हिस्सा गायब हो जाता है। इसलिए उदाहरण के लिए 222/10 परिणाम के रूप में 22 देंगे। फिर इसे 10 के साथ फिर से गुणा करें और आपके पास 220 है। मूल 222 से घटाएं और आप 2 के साथ समाप्त होते हैं, जो जादू द्वारा मूल संख्या में अंतिम अंक के समान है। ;-) लघुकोष्ठक हमें उस क्रम की याद दिलाने के लिए हैं, जिसमें गणना की जाती है। पहले विभाजन और गुणा करें, फिर मूल संख्या से परिणाम घटाएं। हम उन्हें बाहर छोड़ सकते हैं, क्योंकि प्राथमिकता घटाव की तुलना में विभाजन और गुणन के लिए अधिक है, लेकिन यह हमें "अधिक पठनीय" कोड देता है।
अगर हम चाहते तो हम इसे पूरी तरह से अपठनीय बना सकते थे। इससे आधुनिक कंपाइलर के लिए कोई फर्क नहीं पड़ेगा: -
printf("%d%s\n",iToTest,0==(iToTest-iToTest/10*10)%2?" is even":" is odd");
लेकिन यह भविष्य में बनाए रखने के लिए कोड को कठिन बना देगा। जरा कल्पना करें कि आप विषम संख्याओं के लिए पाठ को "नहीं भी है" में बदलना चाहेंगे। फिर कोई और बाद में यह जानना चाहता है कि आपने क्या बदलाव किया है और एक svn भिन्न या समान प्रदर्शन किया है ...
यदि आप पोर्टेबिलिटी के बारे में चिंतित नहीं हैं, लेकिन गति के बारे में अधिक है, तो आप कम से कम महत्वपूर्ण बिट पर एक नज़र डाल सकते हैं। यदि वह बिट 1 पर सेट है, तो यह एक विषम संख्या है, यदि यह 0 है तो यह एक सम संख्या है। थोड़ा एंडियन सिस्टम पर, इंटेल के x86 आर्किटेक्चर की तरह यह कुछ इस तरह होगा: -
if (iToTest & 1) {
// Even
} else {
// Odd
}
यदि आप कुशल होना चाहते हैं, तो बिटवाइज़ ऑपरेटरों ( x & 1
) का उपयोग करें , लेकिन यदि आप पठनीय उपयोग करना चाहते हैं तो मोडुलो 2 ( x % 2
)
%
। यदि आप इसे पढ़ने योग्य बनाना चाहते हैं, तो उपयोग करें %
। हम्म, मैं यहां एक पैटर्न देखता हूं।
सम या विषम की जाँच एक सरल कार्य है।
हम जानते हैं कि किसी भी संख्या में 2 से विभाज्य संख्या और भी विषम है।
हमें बस किसी भी संख्या की विभाज्यता की जांच करने की आवश्यकता है और विभाजन की जाँच के लिए हम %
ऑपरेटर का उपयोग करते हैं
यदि और भी अजीब का उपयोग कर जाँच कर रहा है
if(num%2 ==0)
{
printf("Even");
}
else
{
printf("Odd");
}
C प्रोग्राम यदि और भी उपयोग करने के लिए अजीब है
सशर्त / टर्नरी ऑपरेटर का उपयोग करना
(num%2 ==0) printf("Even") : printf("Odd");
सशर्त ऑपरेटर का उपयोग करके भी या विषम जाँच करने के लिए सी कार्यक्रम ।
Bitwise ऑपरेटर का उपयोग करना
if(num & 1)
{
printf("Odd");
}
else
{
printf("Even");
}
!(i%2) / i%2 == 0
int isOdd(int n)
{
return n & 1;
}
यदि यह बाइनरी में 1 है तो कोड पूर्णांक के अंतिम बिट की जांच करता है
Binary : Decimal
-------------------
0000 = 0
0001 = 1
0010 = 2
0011 = 3
0100 = 4
0101 = 5
0110 = 6
0111 = 7
1000 = 8
1001 = 9
and so on...
ध्यान दें कि सबसे सही बिट हमेशा ऑड नंबर के लिए 1 होता है ।
और बिटवाइज़ AND ऑपरेटर चेकों हमारे में सबसे दायीं ओर बिट वापसी लाइन अगर यह 1 है
जब हम तुलना n के साथ 1 जो साधन 0001
बाइनरी में (शून्य की संख्या फर्क नहीं पड़ता)।
तो चलो बस कल्पना करें कि हमारे पास 1 बाइट के आकार के साथ पूर्णांक n है ।
इसे 8-बिट / 8-बाइनरी अंकों द्वारा दर्शाया जाएगा।
यदि int n 7 था और हम इसकी तुलना 1 से करते हैं , तो यह पसंद है
7 (1-byte int)| 0 0 0 0 0 1 1 1
&
1 (1-byte int)| 0 0 0 0 0 0 0 1
********************************************
Result | F F F F F F F T
कौन सा F असत्य और T सत्य के लिए खड़ा है।
यदि वे दोनों सच हैं तो यह केवल सबसे सही बिट की तुलना करता है। तो, स्वचालित रूप
7 & 1
से टी rue है।
सीधे शब्दों में बदलने n & 1
के लिए n & 2
जो 2 का प्रतिनिधित्व करता है 0010
द्विआधारी में और इतने पर।
मैं हेक्साडेसिमल नोटेशन का उपयोग कर यदि आप आपरेशनों बिटवाइज़ लिए शुरुआत कर रहे हैं सुझाव है
return n & 1;
>> return n & 0x01;
।