整数が偶数か奇数かを確認するにはどうすればよいですか?[閉まっている]
質問
C で指定された数値が偶数か奇数かを確認するにはどうすればよいですか?
解決
モジュロ(%)演算子を使用して、2で除算するときに剰余があるかどうかを確認します。
if (x % 2) { /* x is odd */ }
x <!> amp;を使用するという上記の私の答えを批判している人は少数です。 1は<!> quot; faster <!> quot;です。または<!> quot;より効率的な<!> quot;。これが事実だとは思わない。
好奇心から、2つの簡単なテストケースプログラムを作成しました:
/* 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;
}
次に、マシンの1つでgcc 4.1.3を使用してこれらを5回コンパイルしました。
- 最適化フラグなし。
- -Oを使用
- -Osを使用
- -O2を使用
- -O3を使用
各コンパイルのアセンブリ出力を調べ(gcc -Sを使用)、それぞれの場合に、and.cとmodulo.cの出力が同一であることがわかりました(両方ともandl $ 1、%eax命令を使用しました)。これは<!> quot; new <!> quot;機能、および私はそれが古代バージョンにまでさかのぼると思うまた、最新の(過去20年以内に作られた)非難解なコンパイラ(商用またはオープンソース)には、このような最適化が欠けていると思います。私は他のコンパイラーでテストしますが、現時点では何も利用できません。
他の誰かが他のコンパイラーやプラットフォームのターゲットをテストしたいのに、別の結果が得られたら、知りたいと思います。
最後に、モジュロバージョンは、符号付き整数の実装の表現に関係なく、整数が正、負、またはゼロのいずれでも機能するように標準によって保証されます。ビット単位ANDバージョンはそうではありません。はい、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");
これは、除算または係数を使用するよりも高速です。
[ジョークモード= <!> quot; on <!> quot;]
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;
}
}
[ジョークモード= <!> quot; off <!> quot;]
編集:混乱する値を列挙に追加しました。
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つの関数を含む末尾再帰を使用することに注意してください。コンパイラがSchemeコンパイラのような末尾再帰をサポートしている場合、(while / until種類のループに)効率的に実装できます。この場合、スタックはオーバーフローしないはずです!
数値は、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の場合は偶数になり、そうでない場合は奇数になります。
モジュラス(%)を使用すると、これが簡単になります。
eg。 4%2 = 0したがって、4は偶数 5%2 = 1したがって、5は奇数です
問題のもう1つの解決策
(子供は投票を歓迎します)
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は、n = 2kの整数kが存在する場合でも同じです。
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整数は、指定されたCコンパイルでint
の可能な値を示します。 (C整数は整数のサブセットであることに注意してください。)
C整数の特定のnについて、対応する整数kがC整数内に存在しないかもしれないと心配するかもしれません。しかし、少し証拠があれば、すべての整数nについて、| n | <!> lt; = | 2n | (*)、ここで| n | nが正の場合は<!> quot; nであり、そうでない場合は<!> quot;です。言い換えると、整数のすべてのnに対して、次の少なくとも1つが成り立ちます(実際には、ケース(1と2)またはケース(3と4)のいずれかですが、ここでは証明しません):
ケース1:n <!> lt; = 2n。
ケース2:-n <!> lt; = -2n。
ケース3:-n <!> lt; = 2n。
ケース4:n <!> lt; = -2n。
2k = nになりました。 (nが偶数の場合、そのようなakは存在しますが、ここでは証明しません。nが偶数でない場合、even
のループはとにかく早く戻りません。したがって、k < !> lt; nが0でない場合(*)と、すべてのmについて、整数2m = zのzは、mが0ではない場合にzがmと等しくないことを意味するという事実(ここでも証明されません)。nが0、2 *の場合0 = 0なので、0は完了です(n = 0の場合、nは関数odd
のC整数であるため、0はC整数です。したがって、k = 0はC整数です)。したがって、nが偶数の場合、C整数のそのようなkはC整数のnに対して存在します。
同様の引数は、nが奇数の場合、n = 2k + 1のようなC整数にkが存在することを示しています。
したがって、ここで説明する関数<=>および<=>は、すべての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%を必要とする大差で勝者はor(|)アプローチです。このページのどこにもありません。
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 とのディスカッションのフォローアップです。 彼の答え, しかし、これらの結果を比較したい人にとっては役立つかもしれません。
先生 私が見た限りでは、ロイのアプローチ ((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 のおかげで、3 つのケースはすべて機能的に同等であることがわかりました。ただし、Roy のアプローチは GCC では最適化されていないため、YMMV になります。
これは Visual Studio と似ています。これら 3 つの関数の逆アセンブリ リリース x64 (VS2015) を検査すると、「mod」と「and」の場合は比較部分が同等で、ロイの「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)
ただし、これら 3 つのオプション (プレーン MOD、ビットごとの or、ビットごとの and) を比較するために実際のベンチマークを実行した後、結果は完全に同等でした (ここでも、Visual Studio 2005 x86/x64、リリース ビルド、デバッガーは接続されていません)。
リリースアセンブリは、 test
の指示 and
そして mod
一方、ロイの場合は 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...
}
<!> quot;創造的だが混乱を招くカテゴリ<!> quot;私が提供しています:
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 <!> amp;その場合、実際には1は機能しません。
IsOdd(int x){trueを返します。 }
正当性の証明-すべての正の整数のセットを考慮し、奇数ではない空でない整数のセットがあると仮定します。正の整数は順序が正しいため、奇数ではなく最小の数がありますが、それ自体はかなり奇数であるため、明らかにその数はセットに含まれません。したがって、このセットを空にすることはできません。奇数ではなく最大のものを探すことを除いて、負の整数について繰り返します。
ポータブル:
i % 2 ? odd : even;
非ポータブル:
i & 1 ? odd : even;
i << (BITS_PER_INT - 1) ? odd : even;
一部の人々が投稿しているように、これを行うには多くの方法があります。 thisによるとウェブサイト、最速の方法はモジュラス演算子です:
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 <!> amp; 1作品。
上記の誰かが答えたように、負の数の表現方法がこのメソッドの動作を停止する可能性があることに注意してください。実際、各言語は負のオペランドを処理する方法が異なる可能性があるため、モジュロ演算子メソッドを壊すことさえできます。
ただし、NUMBERが常に正の値であることがわかっている場合、これはうまく機能します。
上記のTooonyのように、バイナリ(およびデナリ)の最後の桁のみが重要であると指摘しました。
ブール論理ANDゲートは、1が返されるために両方の入力が1(または高電圧)でなければならないことを指示します。
1 <!> amp; 0 = 0。
0 <!> amp; 1 = 0。
0 <!> amp; 0 = 0。
1 <!> amp; 1 = 1。
任意の数を2進数で表す場合(ここでは8ビット表現を使用しています)、奇数の末尾には1が、偶数の末尾には0があります。
例:
1 = 00000001
2 = 00000010
3 = 00000011
4 = 00000100
任意の数を取り、ビット単位のAND(Javaでは<!> amp;)を1ずつ使用すると、00000001、= 1が返されます。これは、数が奇数であることを意味します。または00000000 = 0、つまり、数字が偶数であることを意味します。
E.g
奇妙ですか?
1 <!> amp; 1 =
00000001 <!> amp;
00000001 =
00000001 <!> lt; <!>#8212;奇数
2 <!> amp; 1 =
00000010 <!> amp;
00000001 =
00000000 <!> lt; <!>#8212;偶数
54 <!> amp; 1 =
00000001 <!> amp;
00110110 =
00000000 <!> lt; <!>#8212;偶数
これがこれが機能する理由です:
if(number & 1){
//Number is odd
} else {
//Number is even
}
これが冗長な場合はごめんなさい。
数値ゼロパリティ|ゼロ http://tinyurl.com/oexhr3k
Pythonコードシーケンス。
# 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);
}
}
ここで重要なのはコードの3行目です。除算演算子は整数除算を実行するため、結果の小数部が失われます。したがって、たとえば222/10は22になります。次に、それを再び10で乗算すると、220になります。元の222からそれを減算すると、2になります。これは、元の番号の最後の桁と同じ数字です。 ;-) 括弧は、計算が行われる順序を思い出させるためにあります。最初に除算と乗算を行い、次に元の数から結果を引きます。除算よりも除算と乗算の方が優先度が高いため、それらを除外することもできますが、これにより、<!> quot;読みやすい<!> quot;コード。
必要に応じて、すべてを完全に読み取り不可にすることができます。最新のコンパイラーにはまったく違いはありません:-
printf("%d%s\n",iToTest,0==(iToTest-iToTest/10*10)%2?" is even":" is odd");
しかし、それは将来コードを維持するのをより難しくします。奇数のテキストを<!> quot; is not <!> quot;に変更したいと想像してください。その後、他の誰かがあなたが行った変更を見つけてsvn diffなどを実行したい...
移植性については気にせず、速度についてはもっと気にするなら、最下位ビットを見てください。そのビットが1に設定されている場合は奇数、0の場合は偶数です。 Intelのx86アーキテクチャのようなリトルエンディアンシステムでは、次のようになります。-
if (iToTest & 1) {
// Even
} else {
// Odd
}
効率的にしたい場合はビット演算子(x & 1
)を使用しますが、読みやすくしたい場合はモジュロ2(x % 2
)を使用します
偶数または奇数のチェックは簡単なタスクです。
2で割り切れる数値は偶数であり、それ以外は奇数であることがわかっています。
任意の数の可分性をチェックする必要があり、可分性をチェックするには%
演算子
if elseを使用して奇数をチェックする
if(num%2 ==0)
{
printf("Even");
}
else
{
printf("Odd");
}
ifを使用して偶数または奇数をチェックするCプログラムその他
条件付き/三項演算子の使用
(num%2 ==0) printf("Even") : printf("Odd");
C条件演算子を使用して偶数または奇数をチェックするプログラム。
ビットごとの演算子の使用
if(num & 1)
{
printf("Odd");
}
else
{
printf("Even");
}
+66%の高速化<!> gt; !(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です。
<!> amp; ビット単位のAND演算子は、 return 行の右端のビットが1であれば
それを真であると考えてください<!> amp; false
n と 1 を比較すると、バイナリの0001
を意味します(ゼロの数は関係ありません)。
次に、サイズが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 はfalseを表し、 T はtrueを表します。
両方とも正しい場合、右端のビットのみを比較します。したがって、自動的に
7 & 1
は T rueです。
右端の前のビットを確認したい場合はどうなりますか
単にn & 1
をn & 2
に変更します。これは2がバイナリなどで0010
を表します。
ビット単位操作の初心者の場合、16進表記を使用することをお勧めします
return n & 1;
<!> gt; <!> gt; return n & 0x01;
。