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;
}
방법은 훌륭합니다!