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으로 컴파일했습니다.
각 컴파일 (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 가지 방식으로 표현할 수 있다고 규정합니다.
다음과 같이 확인하십시오.
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;
}
방법은 훌륭합니다!
문제에 대한 또 하나의 해결책
(어린이들은 투표를 환영합니다)
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 <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에서 올바르게 작동합니다.
i % 2
훨씬 작고 아마 더 효율적입니다.
%2
는 모든 정수에서 작동합니다.
// C#
bool isEven = ((i % 2) == 0);
typedef
또는 a #define
입니다.
이 시도: 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
이론이나 조립 언어 목록을 생각하는 사람들은 이런 주장을 해결해야하는데 이것은 조심스러운 이야기가되어야합니다. 하늘과 땅에는 철학에서 꿈꾸는 것보다 더 많은 것들이 있습니다.
unsigned x
로 x = x >> 1;
구현 정의 동작 을 그대로 사용 하는 것이 x < 0
좋습니다. 이유 x
와 OrMask
종류가 불분명 합니다. while(x)
테스트를 사용하여 다시 쓸 수있을 정도로 간단합니다 .
% 2
비트 단위를 사용하여 사례 를 컴파일 할만 큼 똑똑해야하기 때문에 이것을 벤치마킹 할 때 사용한 컴파일러가 궁금 합니다 &
. 방금 이것을 테스트했으며 결과는 완전히 동일합니다 (VS2015, 릴리스는 x86 및 x64의 모든 최적화로 빌드). 수락 된 답변은 GCC (2008 년에 작성 됨)에 대해서도 언급합니다.
or
가 비트 단위 보다 빠를 것이라는 전제가 and
거의 없다는 것 입니다. 그런 이상한 플랫폼 / 컴파일러 콤보가 있었더라도 (그리고 벤치 마크를 수행하는 데 사용되는 코드도 게시하지 않았음에도 불구하고) 다른 컴파일러에 따라 동일한 동작을 수행하는 것은 좋지 않은 최적화 베팅입니다. 그래서 내가 쓴 것처럼, 나는 이것이 올바르게 측정되지 않았기 때문에 이것이 어느 플랫폼 / 컴파일러에서 테스트되었는지 궁금 합니다.
이것은 @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
지침 and
과 mod
사례를 사용하지만 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...
}
일부 사람들이 게시 한 것처럼이를 수행하는 방법에는 여러 가지가 있습니다. 에 따르면이 웹 사이트 가장 빠른 방법은 모듈러스 연산자입니다.
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 방법을 알고 있었으며 왜 사용 합니까 ?
우리 연구 중에 부울 대수를 많이하지 않은 사람들을 위해 비트 연산자 방법에 대해 더 자세히 설명하기 위해 여기에 설명이 있습니다. 아마도 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 (java에서 &)를 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
토론을 위해 ...
주어진 숫자의 마지막 숫자 만 보면 짝수인지 홀수인지 확인할 수 있습니다. 부호, 부호 없음, 긍정적, 부정적-이것과 관련하여 모두 동일합니다. 그래서 이것은 모든 라운드에서 작동해야합니다 :-
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");
}
조건부 / 테너 리 연산자 사용
(num%2 ==0) printf("Even") : printf("Odd");
조건부 연산자를 사용하여 짝수 또는 홀수를 확인하는 C 프로그램 .
비트 단위 연산자 사용
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
이진수 를 의미합니다 (0의 숫자는 중요하지 않습니다).
그럼 우리가 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
인 T의 후회.
단순히 변경 n & 1
에 n & 2
2 나타내는0010
이진수 등등.
비트 연산을 처음 접하는 경우 16 진수 표기법을 사용하는 것이 좋습니다
return n & 1;
>> return n & 0x01;
.