[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 번 다른 시간에 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 컴파일러와 같은 테일 재귀를 지원하면 효율적으로 구현할 수 있습니다 (while / 루프 유형으로 바 turn). 이 경우 스택이 오버플로되지 않아야합니다!


답변

2로 나눌 때 나머지가 0 인 경우에도 숫자는 짝수입니다. 2로 나눌 때 나머지가 1이면 숫자는 홀수입니다.

// Java
public static boolean isOdd(int num){
    return num % 2 != 0;
}

/* C */
int isOdd(int num){
    return num % 2;
}

방법은 훌륭합니다!