문제
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;
}
그런 다음 컴퓨터 중 하나에서 GCC 4.1.3으로 5 번을 컴파일했습니다.
- 최적화 플래그가 없습니다.
- -O와 함께
- -os와 함께
- -O2로
- -O3로
나는 각 컴파일의 어셈블리 출력 (GCC -S를 사용)을 검사 한 결과 각각의 경우 및.c 및 modulo.c의 출력이 동일하다는 것을 발견했습니다 (둘 다 AND $ 1, %EAX 명령어를 사용했습니다). 나는 이것이 "새로운"기능이라고 의심하며, 그것이 고대 버전으로 거슬러 올라간 것으로 생각합니다. 또한 현대 (지난 20 년 동안) 비 아케인 컴파일러, 상용 또는 오픈 소스는 그러한 최적화가 부족하다고 의심합니다. 다른 컴파일러를 테스트하지만 현재 사용할 수있는 것은 없습니다.
다른 사람이 다른 컴파일러 및/또는 플랫폼 대상을 테스트하고 다른 결과를 얻는다면 알고 싶습니다.
마지막으로 모듈로 버전은입니다 보장 표준에 따라 정수가 서명 된 정수의 구현의 표현에 관계없이 정수가 양수, 음수 또는 0인지 여부에 따라 작동합니다. 비트와 버전은 아닙니다. 그렇습니다. 나는 둘의 보완이 다소 유비쿼터스라는 것을 알고 있으므로 이것이 실제로 문제가되지 않습니다.
다른 팁
너희들은 너무 효율적이다. 당신이 정말로 원하는 것은 :
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");
이것은 분할 또는 모듈러스를 사용하는 것보다 빠릅니다.
농담 모드 = "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 - 몇 년 전 동료와 똑같은 주장을했는데 그 대답은 아니요, 그것은 음수로 작동하지 않습니다.
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
}
이 방법은 두 가지 함수와 관련된 꼬리 재귀를 사용합니다. 컴파일러가 체계 컴파일러처럼 꼬리 재귀를 지원하는 경우 효율적으로 구현할 수 있습니다 (루프가 끝날 때까지). 이 경우 스택은 오버플로가되어서는 안됩니다!
숫자는 2로 나뉘어 질 때 나머지가 0이더라도 숫자는 0입니다.
// 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).
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은 n = 2k와 같은 정수 k가 존재하더라도입니다.
정수 n은 n = 2k + 1이되는 정수 k가있는 경우 홀수입니다.
다음은 코드입니다.
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- 인테르에 존재하지 않을 것이라고 걱정할 수 있습니다. 그러나 약간의 증거로 모든 정수 n에 대해 n, | n | <= | 2n | (*), 여기서 | n | "n이 양수이고 그렇지 않으면 -n"입니다. 다시 말해, 정수의 모든 N에 대해 다음 중 적어도 하나는 다음 중 하나 이상 (정확히 1 및 2) 또는 사례 (3 및 4)를 실제로 증명하지는 않습니다.
사례 1 : n <= 2n.
사례 2 : -n <= -2n.
사례 3 : -n <= 2n.
사례 4 : n <= -2n.
이제 2k = n을 가져갑니다. (그러한 AK는 N이라면 존재하지만 여기서 증명하지는 않을 것입니다. N이면 심지어 루프가 even
어쨌든 일찍 돌아 오지 않으므로 중요하지 않습니다.) 그러나 이것은 0에 의해 0이 아닌 경우 k <n을 의미합니다. M과 동일하지 않은 M은 0이 아닙니다. 경우 N은 0, 2*0 = 0이므로 0은 우리가 완료됩니다 (N = 0이면 0이 C-Integer에있는 경우 N = 0이면 N이 기능 even
, 따라서 k = 0은 c-integers에 있습니다). 따라서, C- 인테르의 AK는 N이라도 C- 인테르에 N에 대해 존재한다.
비슷한 인수는 n이 홀수 인 경우 c-integers에 n = 2k + 1과 같은 Ak가 존재한다는 것을 보여준다.
따라서 기능 even
그리고 odd
여기에 제시된 것은 모든 C- 인테르 에스에게 제대로 작동합니다.
// 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 내가 본 것에서 Roy의 접근 방식 ((0xFFFFFFFF == (x | 0xFFFFFFFE)
)는 완전히 최적화되지 않습니다 x & 1
로서 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"cases와 같고 Roy의 경우 "또는"사례에 대해 약간 더 크다는 것을 알 수 있습니다.
// 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)
그러나이 세 가지 옵션 (Plain Mod, Bitwise 또는 Bitwise 및)을 비교하기위한 실제 벤치 마크를 실행 한 후 결과는 완전히 동일했습니다 (다시, Visual Studio 2005 x86/x64, 릴리스 빌드, 디버거가 첨부되지 않음).
릴리스 어셈블리를 사용합니다 test
에 대한 지시 and
그리고 mod
Roy의 사례는 다음을 사용합니다 cmp eax,0FFFFFFFFh
접근 방식이지만 무너지고 최적화되어 실제로 차이가 없습니다.
20 번의 실행 후 결과 (i7 3610QM, Windows 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%미만이므로 모든 경우 어셈블리가 동일하다는 것이 분명합니다.
누군가가 시도하고 싶다면 코드는 다음과 같습니다. 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
}
}
비트 방법은 정수의 내부 표현에 따라 다릅니다. 모듈로는 모듈로 연산자가있는 곳 어디에서나 작동합니다. 예를 들어, 일부 시스템은 실제로 태깅에 낮은 레벨 비트를 사용하여 (동적 언어와 같은) RAW 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);
}
완료.
연구 중에 부울 대수학을 많이하지 않은 사람들을 위해 Bitwise Operator 방법에 대해 더 자세히 설명하기 위해 설명이 있습니다. 아마도 OP에 많이 사용되지는 않지만 숫자와 1이 왜 작동하는지 명확하게 생각하는 느낌이 들었습니다.
위의 누군가가 위의 대답과 마찬가지로 음수가 표현되는 방식은이 방법이 작동하지 않을 수 있습니다. 실제로 각 언어는 마이너스 피연산자를 다루는 방식이 다를 수 있기 때문에 모듈로 연산자 방법을 깨뜨릴 수도 있습니다.
그러나 숫자가 항상 긍정적이라는 것을 알고 있다면 이것은 잘 작동합니다.
위의 너무 많은 것은 바이너리 (및 거부)의 마지막 숫자 만 중요하다는 점을 지적했습니다.
부울 로직과 게이트는 두 입력 모두 1을 반환하려면 1 (또는 고전압)이어야한다고 지시합니다.
1 & 0 = 0.
0 & 1 = 0.
0 & 0 = 0.
1 & 1 = 1.
숫자를 바이너리로 나타내는 경우 (여기서 8 비트 표현을 사용했습니다), 홀수는 끝에 1이 1이고 숫자는 0이됩니다.
예를 들어:
1 = 00000001
2 = 00000010
3 = 00000011
4 = 00000100
숫자를 가져 와서 비트를 사용하고 (& 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
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로 끝납니다. 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
}
효율적으로 원한다면 BitWise 연산자를 사용하십시오 (x & 1
), 그러나 읽을 수 있으려면 Modulo 2 (x % 2
)
짝수 또는 이상한 점검은 간단한 작업입니다.
우리는 정확히 2로 나눌 수있는 숫자는 짝수 숫자라는 것을 알고 있습니다.
우리는 단지 숫자의 분할 가능성을 확인하고 사용하는 분할 가능성을 확인하기 만하면됩니다. %
운영자
다른 경우에도 이상한 점검
if(num%2 ==0)
{
printf("Even");
}
else
{
printf("Odd");
}
c 다른 경우 C 프로그램을 사용하거나 홀수를 확인하는 프로그램
조건부/삼여 작업자 사용
(num%2 ==0) printf("Even") : printf("Odd");
C 조건부 운영자를 사용하여 균일하거나 홀수를 확인하는 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입니다 이상한 번호.
그만큼 & 비트와 운영자는 우리의 가장 오른쪽 비트를 확인합니다 반품 1 인 경우 라인
그것을 참 & 거짓으로 생각하십시오
우리가 비교할 때 N ~와 함께 1 이는 의미합니다 0001
바이너리에서 (0의 수는 중요하지 않습니다).
그럼 우리가 정수가 있다고 상상해 봅시다. N 크기가 1 바이트입니다.
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
어느 에프 거짓과 티 사실.
그것 비교 둘 다 사실이라면 가장 옳은 비트입니다. 자동으로
7 & 1
~이다 티후회.
가장 먼저 비트를 확인하고 싶다면 어떻게해야합니까?
단순히 변경됩니다 n & 1
에게 n & 2
2가 나타납니다 0010
이진 등으로.
초보자 인 경우 16 진수 표기법을 사용하는 것이 좋습니다.
return n & 1;
>> return n & 0x01;
.