كيف أعرف إن كان صحيحا حتى أو غريب ؟ [مغلقة]

StackOverflow https://stackoverflow.com/questions/160930

  •  03-07-2019
  •  | 
  •  

سؤال

كيف يمكنني معرفة ما إذا كان العدد زوجي أو فردي في 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;
}

ثم جمعت هذه مع دول مجلس التعاون الخليجي 4.1.3 على آلات مختلفة 5 مرات:

  • مع عدم وجود الأمثل الأعلام.
  • مع -O
  • مع نظام التشغيل
  • مع O2 -
  • مع -O3

أنا درست الجمعية إخراج كل ترجمة (باستخدام دول مجلس التعاون الخليجي -S) وجدت أنه في كل حالة ، الإخراج،.ج نمطية.ج متطابقة (كلاهما يستخدم وأنا $1, %eax التعليمات).أشك في أن هذا هو "جديد" الميزة ، وأظن أنه يعود إلى الإصدارات القديمة.أنا أيضا أشك في أي الحديث (جعلت في الماضي 20 سنوات) غير غامضة مترجم التجارية أو مفتوحة المصدر ، تفتقر إلى مثل هذه الأمثل.وأود أن اختبار على المجمعين ، ولكن ليس لدي أي المتاحة في الوقت الراهن.

إذا كان أي شخص آخر يهتم لاختبار أخرى المجمعين و/أو منصة الأهداف ، ويحصل على نتيجة مختلفة ، سأكون مهتما جدا أن تعرف.

وأخيرا ، مودولو الإصدار هو مضمونة من خلال معيار العمل سواء عدد صحيح هو إيجابي ، سلبي أو صفر ، بغض النظر عن تنفيذ التمثيل وقعت الاعداد الصحيحه.جميع-و هو غير.نعم لقد أدرك المتمم إلى حد ما في كل مكان ، لذلك هذا ليس حقا مشكلة.

نصائح أخرى

هل الرجال waaaaaaaay فعال جدا. ما كنت تريد حقا هو:

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 - لدي بالضبط نفس الحجة مع زميل له منذ سنوات, و الجواب هو لا, لا تعمل مع الأرقام السالبة.

C القياسية على أن الأرقام السالبة يمكن أن تكون ممثلة في 3 طرق:

  • 2 هو تكملة
  • 1 يكمل
  • توقع حجم

التحقق من هذا القبيل:

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. عدد أمر غريب إذا، عندما مقسوما على 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)، ولكن دول مجلس التعاون الخليجي لا تسمح لي أن صفائف من هذه الأحجام:

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];
}

لذلك دعونا بدلا من ذلك اللجوء إلى التعريف الرياضي حتى والغريب بدلا من ذلك.

وهناك ن عدد صحيح حتى في حال وجود أي ك عدد صحيح بحيث ن = 2K.

وهناك ن عدد صحيح هو الغريب في حال وجود أي ك عدد صحيح ان هذه ن = 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-الأعداد الصحيحة هي مجموعة فرعية من الأعداد الصحيحة).

والآن يمكن للمرء أن تقلق ذلك لإعطاء ن في C-الأعداد الصحيحة أن ك عدد صحيح المقابلة قد لا يكون موجودا ضمن C-أعداد صحيحة. ولكن مع إثبات القليل ويمكن أن تظهر أن لجميع الاعداد الصحيحه ن، | ن | <= | 2N | (*)، حيث | ن | هو "ن إذا ن ايجابية و-n غير ذلك". وبعبارة أخرى، لجميع ن في الأعداد الصحيحة واحد على الأقل مما يلي يحمل (إما حالات بالضبط (1 و 2) أو الحالات (3 و 4) في الواقع لكنني لن تثبت ذلك هنا):

والحالة 1: ن <= 2N

وحالة 2: -n <= -2n

والحالة 3: -n <= 2N

وحالة 4: ن <= -2n

والآن تأخذ 2K = ن. (مثل حزب العدالة والتنمية موجود إذا كان n هو حتى، لكنني لن تثبت ذلك هنا. إذا كانت n ليس حتى ذلك الحين فشلت حلقة في even يعود الى لبنان على أي حال، لذلك لا يهم). ولكن هذا يعني ك <ن إذا ن ليست 0 كتبها (*) وحقيقة (مرة أخرى لم يثبت هنا) أن لجميع م، ض في الأعداد الصحيحة 2M = ض ض يعني لا تساوي م نظرا م ليس 0. وفي حالة n غير 0، 2 * 0 = 0 0 حتى هو حتى تتم دينا (إذا كان n = 0 ثم 0 في C-الأعداد الصحيحة لن في C-صحيح في even وظيفة، وبالتالي ك = 0 في C-الأعداد الصحيحة). وهكذا مثل هذا ك في C-الأعداد الصحيحة وجود ل n في C-صحيحة إذا كان n حتى هو.

وهناك حجة مماثلة تبين أن إذا كان n هو الغريب، وجود ك في C-الاعداد الصحيحه ان هذه ن = 2K + 1.

وبالتالي فإن even الوظائف وodd المقدمة هنا تعمل بشكل صحيح لجميع C-أعداد صحيحة.

// C#
bool isEven = ((i % 2) == 0);

وهنا هو الجواب في جافا:

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

وقراءة هذه المناقشة مسلية إلى حد ما، تذكرت أن كان لي في العالم الحقيقي، وظيفة حساسة للوقت أن اختبار الأرقام الفردية والزوجية داخل الحلقة الرئيسية. انها وظيفة السلطة صحيحا، نشرت في مكان آخر على ستاكوفيرفلوو، على النحو التالي. وكانت معايير مثيرة للدهشة تماما. على الأقل في هذه الوظيفة في العالم الحقيقي، على مودولو هو أبطأ و بشكل ملحوظ كذلك. على الفائز، بهامش واسع، الأمر الذي يتطلب 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 النهج٪

وبالنسبة للأشخاص الذين يعتقدون نظرية، أو سرد لغة التجميع، يستقر مثل هذه الحجج، وهذا ينبغي أن يكون حكاية تحذيرية. هناك المزيد من الأشياء في السماء والأرض، هوراشيو، من ويحلم في فلسفتك.

هذا هو متابعة المناقشة مع @RocketRoy فيما يتعلق جوابه, لكن قد تكون مفيدة لمن يريد أن مقارنة هذه النتائج.

tl;dr من ما رأيته روي نهج ((0xFFFFFFFF == (x | 0xFFFFFFFE)) ليس تماما الأمثل x & 1 كما mod النهج لكن في الممارسة تشغيل مرات يجب أن تتحول متساوية في جميع الحالات.

لذا لا مقارنة جمعت الإخراج باستخدام مترجم Explorer:

وظائف اختبار:

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));
}   

رنة 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

دول مجلس التعاون الخليجي 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

القبعات وصولا إلى رنة ، أدركت أن كل ثلاث حالات وظيفيا على قدم المساواة.ومع ذلك روي هذا النهج ليس الأمثل في دول مجلس التعاون الخليجي ، لذلك YMMV.

انها مماثلة مع Visual Studio;تفتيش التفكيك الإصدار 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)

ولكن بعد تشغيل فعلية معيارا لمقارنة هذه الخيارات الثلاثة (عادي وزارة الدفاع ، أحادي المعامل or, and) ، وكانت النتائج متساوية تماما (مرة أخرى ، Visual Studio 2005 x86/x64, بناء الإصدار لا المصحح المرفقة).

الإفراج عن الجمعية يستخدم test تعليمات and و mod الحالات ، بينما روي الحالة يستخدم cmp eax,0FFFFFFFFh النهج, لكنه بشكل كبير بسطه و الأمثل لذلك لا يوجد فرق في الممارسة العملية.

النتائج بعد 20 أشواط (i7 3610QM ويندوز 10 خطة الطاقة تعيين عالية الأداء):

[Test: Plain mod 2 ] AVERAGE TIME: 689.29 ms (Relative diff.: +0.000%)
[Test: Bitwise or  ] AVERAGE TIME: 689.63 ms (Relative diff.: +0.048%)
[Test: Bitwise and ] AVERAGE TIME: 687.80 ms (Relative diff.: -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;
}

أعرف أن هذا هو مجرد النحوية السكر لا تنطبق إلا في .صافي لكن ماذا عن طريقة تمديد...

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
    }
}

وهذه الطريقة المختصة بالبت يعتمد على التمثيل الداخلي من عدد صحيح. سوف مودولو العمل في أي مكان هناك المشغل مودولو. على سبيل المثال، بعض الأنظمة فعلا استخدام البتات مستوى منخفض للعلامات (مثل اللغات الديناميكية)، وبالتالي فإن س الخام و1 لا تعمل فعلا في هذه الحالة.

وIsOdd (كثافة العمليات خ) {العودة الحقيقية. }

وإثبات صحة - النظر في كل مجموعة من الأعداد الصحيحة الموجبة ونفترض أن هناك مجموعة غير فارغة من الأعداد الصحيحة التي ليست غريبة. لأن الأعداد الصحيحة الموجبة هي أمر جيد، وسوف يكون هناك أقل عدد لا الغريب، وهو في حد ذاته أمر غريب جدا، لذلك من الواضح أن العدد لا يمكن أن يكون في المجموعة. لذلك هذه المجموعة لا يمكن أن يكون غير فارغ. كرر الأعداد الصحيحة السالبة إلا نظرة لأكبر عدد فردي لا.

والمحمولة:

i % 2 ? odd : even;

وUnportable:

i & 1 ? odd : even;

i << (BITS_PER_INT - 1) ? odd : even;

وكما نشرت بعض الناس، وهناك العديد من الطرق للقيام بذلك. ووفقا ل هذا موقع و أسرع طريقة هي المشغل معامل:

if (x % 2 == 0)
               total += 1; //even number
        else
               total -= 1; //odd number

ولكن، وهنا بعض <لأ href = "http://cc.davelozinski.com/c-sharp/fastest-way-to-check-if-a-number-is-odd-or-even" يختلط = "نوفولو"> كود الأخرى التي كانت مقاعد البدلاء علامة من قبل المؤلف الذي استمر أبطأ من عملية معامل مشتركة أعلاه:

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 طريقة أو لماذا هم استخدامه ؟؟

int isOdd(int i){
  return(i % 2);
}

والقيام به.

لإعطاء المزيد من التفاصيل بشأن طريقة تشغيل أحادي المعامل لأولئك منا الذين لم تفعل الكثير الجبر منطقية خلال دراساتنا، وهنا تفسيرا لذلك. ربما لم تستخدم من ذلك بكثير إلى OP، لكنني شعرت مما يجعلها واضحة لماذا رقم 1 والأشغال.

تجدر الإشارة مثل ما أجاب شخص ما سبق، فإن الطريقة التي يتم تمثيل الأرقام السالبة يمكن أن يوقف هذا أسلوب العمل. في واقع الأمر يمكن حتى كسر طريقة المشغل مودولو جدا لأن كل لغة يمكن أن تختلف في كيفية تعاملها مع المعاملات السلبية.

ولكن إذا كنت تعرف أن هذا العدد يكون دائما إيجابية، وهذا يعمل بشكل جيد.

وكما Tooony الواردة أعلاه نقطة الا ان الرقم الأخير في ثنائي (وعشري) هو المهم.

وهناك منطق منطقية AND بوابة يفرض أن كل من المدخلات يجب أن تكون 1 (أو ذات الجهد العالي) لمدة 1 يمكن إرجاعها.

1 & 0 = 0.

و0 & 1 = 0.

و0 & 0 = 0.

1 & 1 = 1.

إذا كنت تمثل أي رقم كما ثنائي (ولقد استخدمت تمثيل 8 بت هنا)، الأعداد الفردية لها 1 في النهاية، حتى أرقام لها 0.

وعلى سبيل المثال:

1 = 00000001

2 = 00000010

3 = 00000011

و4 = 00000100

إذا كنت تأخذ أي رقم واستخدام أحادي المعامل AND (وفي جافا) من قبل (1)، وإما العودة 00000001، = 1 وهذا يعني أن عدد أمر غريب. أو 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
I execute this code for ODD & EVEN:

#include <stdio.h>
int main()
{
    int number;
    printf("Enter an integer: ");
    scanf("%d", &number);

    if(number % 2 == 0)
        printf("%d is even.", number);
    else
        printf("%d is odd.", number);
}

لمن أجل مناقشة ...

ما عليك سوى أن ننظر إلى الرقم الأخير في أي عدد معين لمعرفة ما إذا كان الفردية أو الزوجية. وقعت، غير موقعة، إيجابية أو سلبية - انهم جميعا نفس فيما يتعلق بهذا. ولذلك فإن هذا يجب أن تعمل على مدار: -

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");

ولكن من شأنه أن يجعل رمز الطريق الصعب للحفاظ في المستقبل. ولكم أن تتخيلوا أن كنت ترغب في تغيير النص لأرقام غريبة ل"ليس حتى". ثم شخص آخر يريد في وقت لاحق لمعرفة ما هي التغييرات التي قمت بها وأداء فرق إس أو ما شابه ذلك ...

إذا كنت لا تشعر بالقلق حول قابلية ولكن أكثر عن السرعة، هل يمكن أن يكون نظرة على أقل قليلا كبير. إذا تم تعيين هذا الشيء ل1 هو عدد فردي، إذا كان 0 انها عدد زوجي. على نظام endian قليلا، مثل الهندسة المعمارية إنتل x86 لأنه سيكون شيئا من هذا القبيل: -

if (iToTest & 1) {
  // Even
} else {
  // Odd
}

إذا كنت تريد أن تكون كفاءة استخدام مشغلي المختصة بالبت (x & 1)، ولكن إذا كنت تريد أن تكون قابلة للقراءة استخدام مودولو 2 (x % 2)

التحقق أو حتى الغريب هو مهمة بسيطة.

ونحن نعلم أن أي عدد يقبل القسمة على نفسه 2 هو عدد آخر غريب.

علينا فقط أن تحقق القسمة على أي عدد لفحص القسمة نستخدم % المشغل

التحقق من الغريب حتى إذا كان آخر باستخدام

if(num%2 ==0)  
{
    printf("Even");
}
else
{
    printf("Odd");
}

ج برنامج للتحقق من زوجي أو فردي باستخدام لو آخر

باستخدام الشرطي/مشغل الثلاثي

(num%2 ==0) printf("Even") : printf("Odd");

ج برنامج للتحقق من زوجي أو فردي باستخدام المشروط المشغل.

باستخدام المعامل المشغل

if(num & 1)  
{
    printf("Odd");
}
else 
{
    printf("Even");
}

+66% أسرع > !(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 الغريب الأرقام.

على & المعامل و مشغل يتحقق أقصى اليمين قليلا في عودة الخط لو كان 1

أعتقد أنها true & false

عندما نقارن n مع 1 مما يعني 0001 في الثنائية (عدد الأصفار لا يهم).
ثم دعونا فقط تخيل أن لدينا عدد صحيح n مع حجم من 1 بايت.

ستكون ممثلة 8-bit / 8-الأرقام الثنائية.

إذا كان الباحث 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 هو True.

ما إذا كنت ترغب في التحقق قليلا قبل اليمين?

ببساطة تغيير n & 1 إلى n & 2 الذي يمثل 2 0010 في الثنائية وهلم جرا.

أقترح استخدام تدوين ست عشري إذا كنت مبتدئا في جميع العمليات
return n & 1; >> return n & 0x01;.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top