Bagaimana saya bisa memeriksa apakah angka yang diberikan genap atau ganjil dalam C?
Bagaimana saya bisa memeriksa apakah angka yang diberikan genap atau ganjil dalam C?
Jawaban:
Gunakan operator modulo (%) untuk memeriksa apakah ada sisa saat membaginya dengan 2:
if (x % 2) { /* x is odd */ }
Beberapa orang mengkritik jawaban saya di atas yang menyatakan bahwa menggunakan x & 1 adalah "lebih cepat" atau "lebih efisien". Saya tidak percaya ini yang terjadi.
Karena penasaran, saya membuat dua program kasus uji sepele:
/* 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;
}
Saya kemudian mengompilasinya dengan gcc 4.1.3 di salah satu mesin saya 5 kali berbeda:
Saya memeriksa output perakitan dari setiap kompilasi (menggunakan gcc -S) dan menemukan bahwa dalam setiap kasus, output untuk dan.c dan modulo.c adalah identik (mereka berdua menggunakan andl $ 1,% instruksi eax%). Saya ragu ini adalah fitur "baru", dan saya menduga ini berasal dari versi kuno. Saya juga meragukan kompiler non-arcane (komersial dalam 20 tahun terakhir) modern, komersial atau open source, tidak memiliki optimasi seperti itu. Saya akan menguji pada kompiler lain, tetapi saya tidak memiliki yang tersedia saat ini.
Jika ada orang lain yang mau menguji kompiler dan / atau target platform lain, dan mendapatkan hasil yang berbeda, saya akan sangat tertarik untuk mengetahuinya.
Akhirnya, versi modulo dijamin oleh standar untuk bekerja apakah bilangan bulat positif, negatif atau nol, terlepas dari representasi implementasi bilangan bulat yang ditandatangani. Bitwise-dan versinya tidak. Ya, saya menyadari bahwa komplemen dua jenis ini agak ada di mana-mana, jadi ini bukan masalah.
Kalian waaaaaaaay terlalu efisien. Yang Anda inginkan adalah:
public boolean isOdd(int num) {
int i = 0;
boolean odd = false;
while (i != num) {
odd = !odd;
i = i + 1;
}
return odd;
}
Ulangi untuk isEven
.
Tentu saja, itu tidak berfungsi untuk angka negatif. Tetapi dengan kecemerlangan datang pengorbanan ...
Gunakan bit aritmatika:
if((x & 1) == 0)
printf("EVEN!\n");
else
printf("ODD!\n");
Ini lebih cepat daripada menggunakan pembagian atau modulus.
[Mode Joke = "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;
}
}
[Mode Lelucon = "mati"]
EDIT: Menambahkan nilai membingungkan ke enum.
Menanggapi ffpf - saya memiliki argumen yang persis sama dengan seorang rekan bertahun-tahun yang lalu, dan jawabannya adalah tidak , itu tidak bekerja dengan angka negatif.
Standar C menetapkan bahwa angka negatif dapat direpresentasikan dalam 3 cara:
Memeriksa seperti ini:
isEven = (x & 1);
akan bekerja untuk komplemen 2 dan tanda dan representasi besarnya, tetapi tidak untuk komplemen 1.
Namun, saya percaya bahwa yang berikut ini akan berfungsi untuk semua kasus:
isEven = (x & 1) ^ ((-1 & 1) | ((x < 0) ? 0 : 1)));
Terima kasih kepada ffpf karena menunjukkan bahwa kotak teks memakan segalanya setelah karakter saya yang kurang!
Yang bagus adalah:
/*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
}
Perhatikan bahwa metode ini menggunakan rekursi ekor yang melibatkan dua fungsi. Ini dapat diimplementasikan secara efisien (berubah menjadi semacam sementara / sampai loop) jika kompiler Anda mendukung rekursi ekor seperti kompiler Skema. Dalam hal ini tumpukan tidak boleh meluap!
Angka adalah bahkan jika, ketika dibagi dua, sisanya adalah 0. Angka ganjil jika, ketika dibagi 2, sisanya adalah 1.
// Java
public static boolean isOdd(int num){
return num % 2 != 0;
}
/* C */
int isOdd(int num){
return num % 2;
}
Metode sangat bagus!
i % 2 == 0
Saya akan mengatakan hanya membaginya dengan 2 dan jika ada sisa 0, itu genap, kalau tidak aneh.
Menggunakan modulus (%) membuatnya mudah.
misalnya. 4% 2 = 0 karena itu 4 bahkan 5% 2 = 1 oleh karena itu 5 aneh
Satu lagi solusi untuk masalah ini
(anak-anak boleh memilih)
bool isEven(unsigned int x)
{
unsigned int half1 = 0, half2 = 0;
while (x)
{
if (x) { half1++; x--; }
if (x) { half2++; x--; }
}
return half1 == half2;
}
Saya akan membangun tabel paritas (0 jika bahkan 1 jika ganjil) dari bilangan bulat (sehingga orang dapat melakukan pencarian: D), tetapi gcc tidak akan membiarkan saya membuat array dengan ukuran seperti ini:
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];
}
Jadi mari kita beralih ke definisi matematika genap dan gantinya.
Integer n adalah bahkan jika ada integer k sehingga n = 2k.
Suatu bilangan bulat n ganjil jika ada bilangan bulat k sedemikian sehingga n = 2k + 1.
Ini kode untuk itu:
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;
}
Biarkan C-integer menunjukkan nilai yang mungkin dari int
dalam kompilasi C yang diberikan. (Perhatikan bahwa C-integer adalah subset dari integer.)
Sekarang orang mungkin khawatir bahwa untuk n yang diberikan dalam C-integer bahwa k integer yang sesuai mungkin tidak ada dalam C-integer. Tetapi dengan sedikit bukti dapat ditunjukkan bahwa untuk semua bilangan bulat n, | n | <= | 2n | (*), di mana | n | adalah "n jika n positif dan -n sebaliknya". Dengan kata lain, untuk semua n dalam bilangan bulat setidaknya salah satu dari pegangan berikut (tepatnya case (1 dan 2) atau case (3 dan 4) sebenarnya tetapi saya tidak akan membuktikannya di sini):
Kasus 1: n <= 2n.
Kasus 2: -n <= -2n.
Kasus 3: -n <= 2n.
Kasus 4: n <= -2n.
Sekarang ambil 2k = n. (Ak semacam itu memang ada jika n adalah genap, tetapi saya tidak akan membuktikannya di sini. Jika n tidak genap maka loop ineven
gagal kembali lebih awal, jadi itu tidak masalah.) Tapi ini menyiratkan k <n jika n bukan 0 oleh (*) dan fakta (sekali lagi tidak terbukti di sini) bahwa untuk semua m, z dalam bilangan bulat 2m = z menyiratkan z tidak sama dengan m yang diberikan m bukan 0. Dalam kasus n adalah 0, 2 * 0 = 0 jadi 0 bahkan kita sudah selesai (jika n = 0 maka 0 ada di C-integer karena n ada di C-integer dalam fungsi even
, maka k = 0 ada di C-integer). Dengan demikian ak dalam C-integer ada untuk n dalam C-integer jika n adalah genap.
Argumen serupa menunjukkan bahwa jika n ganjil, ada ak di C-integer sehingga n = 2k + 1.
Karenanya fungsi even
dan yang odd
disajikan di sini akan berfungsi dengan baik untuk semua C-integer.
i % 2
jauh lebih kecil dan mungkin lebih efisien.
%2
bekerja untuk semua bilangan bulat.
// C#
bool isEven = ((i % 2) == 0);
typedef
atau #define
atau sesuatu.
Ini jawaban di Jawa:
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();
}
Coba ini: return (((a>>1)<<1) == a)
Contoh:
a = 10101011
-----------------
a>>1 --> 01010101
a<<1 --> 10101010
b = 10011100
-----------------
b>>1 --> 01001110
b<<1 --> 10011100
Membaca diskusi yang agak menghibur ini, saya ingat bahwa saya memiliki dunia nyata, fungsi sensitif waktu yang menguji angka ganjil dan genap di dalam lingkaran utama. Ini adalah fungsi daya integer, diposting di tempat lain di StackOverflow, sebagai berikut. Tolok ukurnya cukup mengejutkan. Setidaknya dalam fungsi dunia nyata ini, modulo lebih lambat , dan sangat signifikan. Pemenang, dengan selisih yang lebar, membutuhkan 67% waktu modulo, adalah pendekatan atau (|) , dan tidak ditemukan di mana pun di halaman ini.
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;
}
Untuk 300 juta loop, timing benchmark adalah sebagai berikut.
3.962 | dan pendekatan topeng
4.851 pendekatan &
5.850 pendekatan%
Untuk orang-orang yang berpikir teori, atau daftar bahasa majelis, menyelesaikan argumen seperti ini, ini harus menjadi kisah peringatan. Ada lebih banyak hal di surga dan bumi, Horatio, daripada yang diimpikan dalam filosofi Anda.
unsigned x
sebagaimana x = x >> 1;
implementasi-didefinisikan perilaku saat x < 0
. Belum jelas alasan x
dan OrMask
jenisnya berbeda. Cukup sederhana untuk menulis ulang menggunakan while(x)
tes.
% 2
kasing menggunakan bitwise &
. Saya baru saja menguji ini dan hasilnya benar-benar sama (VS2015, Rilis dibangun dengan semua optimisasi, baik x86 dan x64). Jawaban yang diterima juga menyatakan ini untuk GCC (ditulis pada 2008).
or
akan lebih cepat daripada and
sangat tidak mungkin, pada platform / kompiler. Bahkan jika ada kombinasi platform / kompiler yang aneh (dan Anda belum mempostingnya atau kode yang digunakan untuk melakukan benchmark), tergantung pada kompiler lain untuk berperilaku yang sama akan menjadi taruhan optimasi yang buruk. Jadi, ketika saya menulis, saya bertanya-tanya di platform / kompiler mana ini diuji , karena saya hampir yakin itu tidak diukur dengan benar.
Ini adalah tindak lanjut dari diskusi dengan @RocketRoy mengenai jawabannya , tetapi mungkin bermanfaat bagi siapa saja yang ingin membandingkan hasil ini.
tl; dr Dari apa yang saya lihat, pendekatan Roy ( (0xFFFFFFFF == (x | 0xFFFFFFFE)
) tidak sepenuhnya dioptimalkan x & 1
sebagai mod
pendekatan, tetapi dalam praktiknya waktu berjalan seharusnya menjadi sama dalam semua kasus.
Jadi, pertama saya membandingkan output yang dikompilasi menggunakan Compiler Explorer :
Fungsi yang diuji:
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));
}
Klik 3.9.0 dengan -O3:
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
GCC 6.2 dengan -O3:
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
Angkat ke CLang, itu menyadari bahwa ketiga kasus secara fungsional sama. Namun, pendekatan Roy tidak dioptimalkan dalam GCC, begitu YMMV.
Ini mirip dengan Visual Studio; memeriksa Rilis pembongkaran x64 (VS2015) untuk tiga fungsi ini, saya bisa melihat bahwa bagian perbandingannya sama untuk case "mod" dan "dan", dan sedikit lebih besar untuk case Roy "atau":
// 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)
Namun, setelah menjalankan tolok ukur yang sebenarnya untuk membandingkan tiga opsi ini (mod sederhana, bitwise atau, bitwise dan), hasilnya benar-benar sama (sekali lagi, Visual Studio 2005 x86 / x64, rilis Rilis, tidak ada debugger terpasang).
Majelis rilis menggunakan test
instruksi untuk and
dan mod
kasus, sedangkan kasus Roy menggunakancmp eax,0FFFFFFFFh
pendekatan, tetapi sangat terbuka dan dioptimalkan sehingga tidak ada perbedaan dalam prakteknya.
Hasil saya setelah 20 berjalan (i7 3610QM, rencana daya Windows 10 diatur ke Kinerja Tinggi):
[Tes: Plain mod 2] WAKTU RATA-RATA: 689,29 ms (Perbedaan relatif .: + 0,000%) [Tes: Bitwise atau] WAKTU RATA-RATA: 689,63 ms (Perbedaan relatif .: + 0,048%) [Tes: Bitwise dan] WAKTU RATA-RATA: 687,80 ms (Perbedaan relatif .: -0,217%)
Perbedaan antara opsi-opsi ini kurang dari 0,3%, jadi agak jelas rakitannya sama dalam semua kasus.
Berikut adalah kode jika ada yang ingin mencoba, dengan peringatan bahwa saya hanya mengujinya pada Windows (periksa #if LINUX
persyaratan untuk get_time
definisi dan menerapkannya jika perlu, diambil dari jawaban ini ).
#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;
}
Saya tahu ini hanya gula sintaksis dan hanya berlaku di .net tetapi bagaimana dengan metode ekstensi ...
public static class RudiGroblerExtensions
{
public static bool IsOdd(this int i)
{
return ((i % 2) != 0);
}
}
Sekarang Anda dapat melakukan hal berikut
int i = 5;
if (i.IsOdd())
{
// Do something...
}
Dalam "kategori kreatif tapi membingungkan" saya menawarkan:
int isOdd(int n) { return n ^ n * n ? isOdd(n * n) : n; }
Varian pada tema ini yang khusus untuk 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
}
}
Metode bitwise tergantung pada representasi bagian dalam bilangan bulat. Modulo akan bekerja di mana saja ada operator modulo. Sebagai contoh, beberapa sistem benar-benar menggunakan bit level rendah untuk penandaan (seperti bahasa dinamis), sehingga x & 1 mentah tidak akan benar-benar berfungsi dalam kasus itu.
IsOdd (int x) {return true; }
Bukti kebenaran - pertimbangkan himpunan semua bilangan bulat positif dan anggap ada satu set bilangan bulat yang tidak kosong yang tidak aneh. Karena bilangan bulat positif disusun dengan baik, akan ada bilangan terkecil bukan bilangan ganjil, yang dengan sendirinya cukup aneh, sehingga jelas bilangan itu tidak dapat diatur. Karenanya set ini tidak boleh kosong. Ulangi untuk bilangan bulat negatif kecuali mencari bilangan terbesar bukan ganjil.
Seperti yang telah diposting beberapa orang, ada banyak cara untuk melakukan ini. Menurut situs web ini , cara tercepat adalah operator modulus:
if (x % 2 == 0)
total += 1; //even number
else
total -= 1; //odd number
Namun, berikut adalah beberapa kode lain yang ditandai oleh penulis yang berjalan lebih lambat daripada operasi modulus umum di atas:
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
Berapa banyak orang yang tahu tentang metode Math.System.DivRem atau mengapa mereka menggunakannya ??
int isOdd(int i){
return(i % 2);
}
selesai
Untuk memberikan elaborasi lebih lanjut tentang metode operator bitwise bagi kita yang tidak melakukan banyak aljabar boolean selama studi kami, berikut adalah penjelasannya. Mungkin tidak banyak berguna untuk OP, tapi saya ingin menjelaskan mengapa NUMBER & 1 berfungsi.
Harap perhatikan seperti ketika seseorang menjawab di atas, cara angka negatif ditampilkan dapat menghentikan metode ini berfungsi. Bahkan ia dapat merusak metode operator modulo juga karena masing-masing bahasa dapat berbeda dalam bagaimana berurusan dengan operan negatif.
Namun jika Anda tahu bahwa NUMBER akan selalu positif, ini berfungsi dengan baik.
Seperti Tooony di atas menyatakan bahwa hanya digit terakhir dalam biner (dan denary) yang penting.
Logika AND gerbang boolean menentukan bahwa kedua input harus berupa 1 (atau tegangan tinggi) agar 1 dikembalikan.
1 & 0 = 0.
0 & 1 = 0.
0 & 0 = 0.
1 & 1 = 1.
Jika Anda mewakili angka apa pun sebagai biner (saya telah menggunakan representasi 8 bit di sini), angka ganjil memiliki 1 di akhir, bahkan angka memiliki 0.
Sebagai contoh:
1 = 00000001
2 = 00000010
3 = 00000011
4 = 00000100
Jika Anda mengambil nomor apa pun dan menggunakan bitwise AND (& dalam java) dengan 1 maka akan mengembalikan 00000001, = 1 yang berarti angkanya ganjil. Atau 00000000 = 0, artinya angkanya genap.
Misalnya
Aneh?
1 & 1 =
00000001 &
00000001 =
00000001 <- Ganjil
2 & 1 =
00000010 &
00000001 =
00000000 <- Merata
54 & 1 =
00000001 &
00110110 =
00000000 <- Merata
Inilah mengapa ini bekerja:
if(number & 1){
//Number is odd
} else {
//Number is even
}
Maaf jika ini berlebihan.
Angka nol paritas | nol http://tinyurl.com/oexhr3k
Urutan kode 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))
Keluaran:
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);
}
Demi diskusi ...
Anda hanya perlu melihat angka terakhir di nomor mana saja untuk melihat apakah angka itu genap atau ganjil. Ditandatangani, tidak ditandatangani, positif, negatif - semuanya sama dalam hal ini. Jadi ini harus bekerja sepanjang: -
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);
}
}
Kuncinya di sini adalah di baris ketiga kode, operator divisi melakukan divisi integer, sehingga hasilnya hilang bagian fraksi dari hasil. Jadi misalnya 222/10 akan memberikan 22 hasilnya. Kemudian kalikan lagi dengan 10 dan Anda memiliki 220. Kurangi itu dari yang asli 222 dan Anda berakhir dengan 2, yang dengan sihir adalah angka yang sama dengan angka terakhir di angka asli. ;-) Tanda kurung ada di sana untuk mengingatkan kita tentang urutan perhitungan yang dilakukan. Pertama lakukan pembagian dan perkaliannya, kemudian kurangi hasilnya dari angka aslinya. Kita dapat mengabaikannya, karena prioritas lebih tinggi untuk pembagian dan penggandaan daripada pengurangan, tetapi ini memberi kita kode "lebih mudah dibaca".
Kita bisa membuat semuanya benar-benar tidak dapat dibaca jika kita mau. Tidak ada bedanya untuk kompiler modern: -
printf("%d%s\n",iToTest,0==(iToTest-iToTest/10*10)%2?" is even":" is odd");
Tapi itu akan membuat kode lebih sulit untuk dipertahankan di masa depan. Bayangkan saja Anda ingin mengubah teks untuk angka ganjil menjadi "tidak genap". Kemudian orang lain di kemudian hari ingin mengetahui perubahan apa yang Anda buat dan melakukan svn diff atau yang serupa ...
Jika Anda tidak khawatir tentang portabilitas tetapi lebih banyak tentang kecepatan, Anda bisa melihat sedikit yang paling signifikan. Jika bit itu diatur ke 1 itu adalah angka ganjil, jika itu 0 itu adalah angka genap. Pada sistem endian kecil, seperti arsitektur x86 Intel akan menjadi seperti ini: -
if (iToTest & 1) {
// Even
} else {
// Odd
}
Jika Anda ingin menjadi efisien, gunakan operator bitwise ( x & 1
), tetapi jika Anda ingin dibaca, gunakan modulo 2 ( x % 2
)
%
. Jika Anda ingin dapat dibaca, gunakan %
. Hmmm, saya melihat polanya di sini.
Memeriksa genap atau ganjil adalah tugas sederhana.
Kita tahu bahwa angka apa pun yang dapat habis dibagi 2 adalah angka genap.
Kami hanya perlu memeriksa pembagian nomor apa pun dan untuk memeriksa pembagian, kami menggunakan %
operator
Memeriksa bahkan aneh menggunakan jika lain
if(num%2 ==0)
{
printf("Even");
}
else
{
printf("Odd");
}
Program C untuk memeriksa genap atau ganjil menggunakan jika lain
Menggunakan operator Conditional / Ternary
(num%2 ==0) printf("Even") : printf("Odd");
Program C untuk memeriksa genap atau ganjil menggunakan operator kondisional .
Menggunakan operator Bitwise
if(num & 1)
{
printf("Odd");
}
else
{
printf("Even");
}
!(i%2) / i%2 == 0
int isOdd(int n)
{
return n & 1;
}
Kode memeriksa bit terakhir dari integer jika 1 dalam Binary
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...
Perhatikan bit paling kanan selalu 1 untuk nomor Ganjil .
yang & bitwise operator AND cek bit paling kanan di kami kembali baris jika itu 1
Ketika kita membandingkan n dengan 1 yang berarti 0001
dalam biner (jumlah nol tidak masalah).
maka mari kita bayangkan saja kita memiliki bilangan bulat n dengan ukuran 1 byte.
Itu akan diwakili oleh 8-bit / 8-binary digit.
Jika int n adalah 7 dan kami membandingkannya dengan 1 , Ini seperti
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
Yang F adalah false dan T untuk true.
Itu hanya membandingkan bit paling kanan jika keduanya benar. Jadi, secara otomatis
7 & 1
adalah T rue.
Hanya mengubah n & 1
ke n & 2
yang 2 mewakili 0010
di Binary dan sebagainya.
Saya sarankan menggunakan notasi heksadesimal jika Anda seorang pemula untuk operasi bitwise
return n & 1;
>> return n & 0x01;
.