Programming

정수가 짝수인지 홀수인지 어떻게 확인합니까?

procodes 2020. 5. 11. 21:16
반응형

정수가 짝수인지 홀수인지 어떻게 확인합니까? [닫은]


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 번 다른 시간에 gcc 4.1.3으로 컴파일했습니다.

  • 최적화 플래그가 없습니다.
  • -O로
  • -O로
  • -O2로
  • -O3 사용

각 컴파일 (gcc -S 사용)의 어셈블리 출력을 조사한 결과 각 경우에 and.c와 modulo.c의 출력이 동일하다는 것을 알았습니다 (둘 다 andl $ 1, % eax 명령을 사용했습니다). 나는 이것이 "새로운"기능이라고 의심하고, 그것이 고대 버전으로 거슬러 올라간다고 생각한다. 또한 상업용 또는 오픈 소스와 같은 현대 (비록 20 년 동안 만들어진) 비-아칸 컴파일러가 그러한 최적화가 부족한 것으로 의심합니다. 다른 컴파일러에서 테스트하려고하지만 현재 사용할 수있는 제품이 없습니다.

다른 누군가가 다른 컴파일러 및 / 또는 플랫폼 대상을 테스트하고 다른 결과를 얻으려는 경우 매우 관심이 있습니다.

마지막으로 모듈로 버전은 구현에서 부호있는 정수의 표현에 관계없이 정수가 양수인지, 음수인지 또는 0인지를 표준으로 보장 합니다. 비트 및 버전이 아닙니다. 예, 2의 보수가 어느 곳에서나 유비쿼터스라는 것을 알고 있으므로 실제로는 문제가되지 않습니다.


너희들은 너무 효율적이다. 당신이 정말로 원하는 것은 :

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

분할 또는 계수를 사용하는 것보다 빠릅니다.


[Joke mode = "on"]

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에 대한 응답으로 -몇 년 전 동료와 정확히 같은 주장을했으며 대답은 no 이며 음수로는 작동하지 않습니다.

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
}

이 방법은 두 가지 기능이 포함 된 테일 재귀를 사용합니다. 컴파일러가 Scheme 컴파일러와 같은 테일 재귀를 지원하는 경우 효율적으로 구현할 수 있습니다 (언제 / 루프가 될 때까지). 이 경우 스택이 오버플로되지 않아야합니다!


2로 나눌 때 나머지가 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;
}

정수의 패리티 (홀수이면 1 일 경우 0)의 테이블을 작성하므로 (검색 : 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 = 2k + 1과 같은 정수 k가 존재하면 정수 n은 홀수입니다.

코드는 다음과 같습니다.

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-integers int가 주어진 C 컴파일에서 가능한 값을 나타냅니다 . C-integers는 정수의 하위 집합입니다.

이제 C-integers에서 주어진 n에 대해 해당 정수 k가 C-integers 내에 존재하지 않을 것이라고 걱정할 수 있습니다. 그러나 약간의 증거로 모든 정수 n, | n | <= | 2n | (*), 여기서 | n | "n이 양수이면 n이고 그렇지 않으면 -n"입니다. 다시 말해, 정수의 모든 n에 대해 다음 중 하나 이상을 보유합니다 (사실 사례 (1 및 2) 또는 사례 (3 및 4)이지만 실제로는 증명하지 않습니다).

사례 1 : n <= 2n.

사례 2 : -n <= -2n.

사례 3 : -n <= 2n.

사례 4 : n <= -2n.

이제 2k = n을 취하십시오. (n은 짝수이면 이러한 ak가 존재하지만 여기서 증명하지는 않습니다. n이 짝 수면 루프 인은 even어쨌든 일찍 리턴하지 못하므로 문제가되지 않습니다.) 그러나 이것은 n이면 k <n을 의미합니다. 0으로 (*)가 아니며 모든 m에 대해 정수 2m = z의 z는 m이 0이 아닌 m과 같지 않은 z를 의미합니다. n이 0 인 경우, 2 * 0 = 0 따라서 0도 완료됩니다 (n = 0이면 0은 C 정수에 있습니다 .n은 C 정수에 even있기 때문에 k = 0은 C 정수에 있습니다). 따라서 C-integers의 이러한 ak는 n이 짝수이면 C-integers의 n에 존재합니다.

비슷한 주장은 n이 홀수이면 C-integers에 n = 2k + 1과 같은 ak가 있음을 보여줍니다.

따라서 여기에 제시된 기능 even기능 odd은 모든 C-integers에서 올바르게 작동합니다.


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

다음은 Java 답변입니다.

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의 다른 곳에 게시 된 정수 전력 함수입니다. 벤치 마크는 매우 놀랍습니다. 적어도이 실제 함수에서는 모듈로가 느리고 상당히 중요합니다. 승자는 모듈로 시간의 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;
}

3 억 루프의 경우 벤치 마크 타이밍은 다음과 같습니다.

3.962 | 마스크 접근

4.851 & 접근

% 접근법 5.850

이론이나 조립 언어 목록을 생각하는 사람들은 이와 같은 주장을 해결해야하는데 이것은 조심스러운 이야기가되어야합니다. 하늘과 땅에는 철학에서 꿈꾸는 것보다 더 많은 것들이 있습니다.


이것은 @RocketRoy 와의 답변 에 대한 후속 조치 이지만 이러한 결과를 비교하려는 사람에게는 유용 할 수 있습니다.

TL; DR 내가 본 바로는이 로이의 접근 방식은 ( (0xFFFFFFFF == (x | 0xFFFFFFFE)) 완전히 최적화되지 x & 1는 AS 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));
}   

-O3을 포함한 CLang 3.9.0 :

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

-O3을 사용하는 GCC 6.2 :

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

CLang에 이르기까지 세 가지 경우 모두 기능적으로 동일하다는 것을 깨달았습니다. 그러나 Roy의 접근 방식은 GCC에서 최적화되지 않으므로 YMMV입니다.

Visual Studio와 비슷합니다. 이 세 가지 기능에 대한 디스 어셈블리 릴리스 x64 (VS2015)를 검사하면 비교 부분이 "mod"및 "and"경우와 같고 Roy의 "or"경우에는 약간 더 큽니다.

// 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)

그러나 이러한 세 가지 옵션 (일반 모드, 비트 단위 또는 비트 단위)을 비교하기위한 실제 벤치 마크를 실행 한 후에는 결과가 완전히 동일했습니다 (Visual Studio 2005 x86 / x64, 릴리스 빌드, 디버거 없음).

릴리스 어셈블리는 test지침 andmod사례를 사용하지만 Roy의 사례는 cmp eax,0FFFFFFFFh접근 방식을 사용 하지만 크게 풀리고 최적화되어 실제로 차이가 없습니다.

20 회 실행 후 결과 (i7 3610QM, Windows 10 전원 관리 옵션이 고성능으로 설정 됨) :

[테스트 : Plain mod 2] 평균 시간 : 689.29 ms (상대 차이 : + 0.000 %)
[테스트 : 비트 단위 또는] 평균 시간 : 689.63 ms (상대 차이 : + 0.048 %)
[테스트 : 비트 및] 평균 시간 : 687.80 ms (상대 차이 : -0.217 %)

이러한 옵션의 차이는 0.3 % 미만이므로 모든 경우에 어셈블리가 동일하다는 것이 분명합니다.

누군가가 시도하고 싶다면 Windows에서만 테스트해야한다는 경고와 함께 코드가 있습니다 ( 정의 #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) {return true; }

정확성 증명-모든 양의 정수 세트를 고려하고 홀수가 아닌 정수가 아닌 정수 세트가 있다고 가정하십시오. 양의 정수는 잘 정렬되어 있기 때문에 홀수가 아닌 가장 작은 수가 있으며, 그 자체로는 꽤 홀수이므로 숫자가 세트에있을 수 없습니다. 따라서이 세트는 비어 있지 않아야합니다. 홀수가 아닌 가장 큰 숫자를 찾는 것을 제외하고 음의 정수에 대해 반복하십시오.


가지고 다닐 수 있는:

i % 2 ? odd : even;

휴대 불가 :

i & 1 ? odd : even;

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

일부 사람들이 게시 한 것처럼이를 수행하는 방법에는 여러 가지가 있습니다. 이 웹 사이트 에 따르면 가장 빠른 방법은 모듈러스 연산자입니다.

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 방법을 알고 있었으며 왜 사용 합니까 ?


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

끝난.


연구 중에 부울 대수를 많이하지 않은 사람들을 위해 비트 연산자 방법에 대해 더 자세히 설명하기 위해 여기에 설명이 있습니다. 아마도 OP에는별로 유용하지 않지만 NUMBER & 1이 왜 작동하는지 명확하게 느끼고 싶었습니다.

위의 답변과 같이 음수가 표시되는 방식으로 인해이 방법이 작동하지 않을 수 있습니다. 실제로 각 언어가 음수 피연산자를 처리하는 방식이 다를 수 있으므로 모듈로 연산자 메소드를 손상시킬 수도 있습니다.

그러나 NUMBER가 항상 양수라는 것을 알고 있다면 잘 작동합니다.

위의 Tooony는 2 진 (및 치열)의 마지막 숫자 만 중요하다는 점을 지적했습니다.

부울 논리 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");

그러나 향후 코드 유지 관리가 더 어려워 질 것입니다. 홀수에 대한 텍스트를 "짝수"로 변경한다고 상상해보십시오. 그런 다음 나중에 다른 사람이 변경 사항을 확인하고 svn diff 또는 이와 유사한 것을 수행하려고합니다 ...

이식성에 대해 걱정하지 않고 속도에 대해 더 걱정한다면 가장 중요한 부분을 살펴볼 수 있습니다. 해당 비트가 1로 설정되면 홀수이고, 0이면 짝수입니다. Intel의 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");

조건부 연산자를 사용하여 짝수 또는 홀수를 확인하는 C 프로그램 .

비트 단위 연산자 사용

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 홀수 번호.

우리의 오른쪽 비트 비트 AND 연산자 수표 반송 라인이 1이라면

그것을 참과 거짓으로 생각하십시오

우리가 n1비교할 때 0001이진수 를 의미합니다 (0의 숫자는 중요하지 않습니다).
그럼 우리가 1 바이트 크기의 정수 n가지고 있다고 상상해 봅시다 .

8 비트 / 8 이진수로 표현됩니다.

int n7 이고 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 & 1T의 후회.

가장 오른쪽에있는 비트를 확인하려면 어떻게합니까?

단순히 변경 n & 1n & 22 나타내는 0010이진수 등등.

비트 연산을 처음 접하는 경우 16 진수 표기법을 사용하는 것이 좋습니다
return n & 1;>> return n & 0x01;.

참고 URL : https://stackoverflow.com/questions/160930/how-do-i-check-if-an-integer-is-even-or-odd

반응형