Як я можу перевірити, чи задане число парне чи непарне в С?
Як я можу перевірити, чи задане число парне чи непарне в С?
Відповіді:
Використовуйте оператор modulo (%), щоб перевірити, чи є залишок під час ділення на 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 різних разів:
Я вивчив вихідний збір кожного компілятора (використовуючи gcc -S) і виявив, що в кожному випадку вихід для and.c і modulo.c був однаковим (вони обидва використовували інструкцію andl $ 1,% eax). Я сумніваюся, що це "нова" особливість, і я підозрюю, що вона датується давніми версіями. Я також сумніваюсь, що будь-якому сучасному (зробленому за останні 20 років) компіляторові, що не є прихованим, комерційним чи відкритим кодом, такої оптимізації не вистачає. Я б протестував на інших компіляторах, але на даний момент у мене немає доступних.
Якщо хтось би потурбувався протестувати інші компілятори та / або цілі платформи, і отримав інший результат, мені було б дуже цікаво знати.
Нарешті, версія модуля гарантується стандартом для роботи, чи є ціле число позитивним, від'ємним або нульовим, незалежно від подання реалізацією підписаних цілих чисел. Побітова версія і ні. Так, я розумію, що доповнення двох є дещо повсюдним, тому це насправді не проблема.
Ви, хлопці, занадто ефективні. Те, що ти насправді хочеш:
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");
Це швидше, ніж використання поділу чи модуля.
[Жарт режим = "увімкнено]]
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;
}
}
[Жарт режим = "вимкнено"]
EDIT: До перерахунків додано заплутані значення.
У відповідь на ffpf - у мене був такий самий аргумент з колегою років тому, і відповідь - ні , це не працює з негативними цифрами.
Стандарт С передбачає, що від'ємні числа можна представити трьома способами:
Перевірка так:
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
}
Зауважте, що цей метод використовує хвостову рекурсію, що включає дві функції. Це може бути ефективно реалізовано (перетворюється на деякий час / до виду циклу), якщо ваш компілятор підтримує хвостову рекурсію, як компілятор схеми. У цьому випадку стек не повинен переповнюватися!
Число є навіть, якщо, поділене на два, решта дорівнює 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 залишок, це парне, інакше це дивно.
Використання модуля (%) робить це просто.
напр. 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;
}
Я створив би таблицю паритетів (0, якщо навіть 1, якщо непарне) цілих чисел (так що можна було б зробити пошук: 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 є непарним, якщо існує ціле число k таке, що n = 2k + 1.
Ось код для цього:
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;
}
Нехай С-цілі числа позначають можливі значення int
в даній компіляції С. (Зверніть увагу, що С-цілі числа - це підмножина цілих чисел.)
Тепер можна потурбуватися, що для заданого n у C-цілих числах відповідне ціле число k може не існувати в межах C-цілих чисел. Але з невеликим доказом можна показати, що для всіх цілих чисел 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. (Такий ak існує, якщо n є рівним, але я цього не докажу. Якщо n навіть немає, петля все-таки even
не повертається рано, тому це не має значення.) Але це означає k <n, якщо n не 0 по (*), а факт (знову тут не доведено), що для всіх m, z у цілих числах 2m = z випливає, що z не дорівнює m, m не дорівнює 0. У випадку n дорівнює 0, 2 * 0 = 0 значить, 0 навіть ми робимо (якщо n = 0, тоді 0 знаходиться в C-цілих числах, тому що n знаходиться в C-цілому цілі функції even
, отже, k = 0 знаходиться в C-цілих числах). Таким чином, такі ak в C-цілих числах існують для n в C-цілих числах, якщо n є парним.
Подібний аргумент показує, що якщо n непарне, існує C в цілих цілих числах таких, що n = 2k + 1.
Отже, функція even
і odd
представлена тут буде працювати для всіх C-цілих чисел.
i % 2
набагато менший і, мабуть, більш ефективний.
%2
працює для всіх цілих чисел.
// C#
bool isEven = ((i % 2) == 0);
typedef
або #define
або що - то.
Ось відповідь на 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;
}
Для 300 мільйонів циклів терміни орієнтиру такі.
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
як 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));
}
CLang 3.9.0 з -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 з -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
Капелюхи до CLang, він зрозумів, що всі три випадки функціонально рівні. Однак підхід Роя не оптимізований в GCC, тому YMMV.
Подібно до Visual Studio; оглядаючи демонтаж випуску x64 (VS2015) для цих трьох функцій, я міг побачити, що частина порівняння дорівнює для "mod" і "і" випадків, і трохи більша для випадку 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)
Однак після запуску фактичного еталону для порівняння цих трьох варіантів (звичайний мод, побітовий або побітовий і) результати були повністю рівними (знову ж таки, Visual Studio 2005 x86 / x64, випуск версії, відладчик не додається).
Збірка випуску використовує test
інструкцію для and
та mod
випадків, тоді як у випадку Роя використовується cmp eax,0FFFFFFFFh
підхід, але він сильно розкручений та оптимізований, тому різниці у практиці немає.
Мої результати після 20 запусків (i7 3610QM, план живлення Windows 10 встановлено на високу продуктивність):
[Тест: Звичайний мод 2] СРІДНИЙ ЧАС: 689,29 мс (Відносна різниця: + 0,000%) [Тест: Побітовий або] СРІДНИЙ ЧАС: 689,63 мс (Відносна різниця: + 0,048%) [Тест: Побітові та] СРІДНИЙ ЧАС: 687,80 мс (Відносна різниця: -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
}
}
Розрядний метод залежить від внутрішнього подання цілого числа. Модуло працюватиме в будь-якому місці, де є модуль оператора. Наприклад, деякі системи насправді використовують біти низького рівня для позначення тегів (наприклад, динамічні мови), тому сировина x & 1 насправді не працюватиме в такому випадку.
IsOdd (int x) {return true; }
Доказ правильності - розглянемо набір усіх натуральних чисел та припустимо, що існує не порожній набір цілих чисел, які не є непарними. Оскільки позитивні цілі числа добре впорядковані, вийде найменше не непарне число, яке саме по собі є досить непарним, тому однозначно це число не може бути в наборі. Тому цей набір не може бути порожнім. Повторіть для від'ємних цілих чисел, за винятком найбільшого нечетного числа.
Як опублікували деякі люди, існує чимало способів зробити це. За даними цього веб-сайту , найшвидший спосіб - це оператор модуля:
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 або навіщо його використовувати ??
Щоб детальніше розглянути метод побітових операторів для тих із нас, хто не робив великої булевої алгебри під час наших досліджень, ось пояснення. Напевно, не дуже корисно для ОП, але я відчув, як зрозуміти, чому НОМЕР і 1 працює.
Зауважте, як, як хтось відповів вище, спосіб представлення негативних чисел може зупинити цей метод роботи. Насправді він навіть може порушити метод оператора модуля, оскільки кожна мова може відрізнятися тим, як він має справу з негативними операндами.
Однак якщо ви знаєте, що НОМЕР завжди буде позитивним, це добре працює.
Оскільки Тоуні вище зазначав, що важлива лише остання цифра у двійковій (і денарійній) формі.
Булева логіка І ворота диктує, що обидва входи повинні бути рівними 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
Послідовність коду 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);
}
}
Ключ тут - у третьому рядку коду, оператор ділення виконує ціле ділення, так що в результаті не вистачає частки результату. Так, наприклад, 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
), але якщо ви хочете читати, використовуйте modulo 2 ( x % 2
)
%
. Якщо ви хочете, щоб воно було читабельним, використовуйте %
. Хммм, я бачу тут візерунок.
Перевірка парного чи непарного - це просте завдання.
Ми знаємо, що будь-яке число, яке точно ділиться на 2, є парним числом.
Нам просто потрібно перевірити подільність будь-якої кількості і для перевірки подільності ми використовуємо %
оператор
Перевірка парного використання, якщо інше
if(num%2 ==0)
{
printf("Even");
}
else
{
printf("Odd");
}
Програма C, щоб перевірити парне або непарне використання, якщо інше
Використання умовного / термінального оператора
(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 для непарних чисел.
в & побітовое І оператор перевіряє правий біт в нашій повернутої рядку , якщо це 1
Коли ми порівнюємо n з 1, що означає 0001
двійкові (кількість нулів не має значення).
то давайте просто уявімо, що у нас є ціле число 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
Який F означає false, а T - true.
Він порівнює лише самий крайній біт, якщо вони обоє істинні. Отже, автоматично
7 & 1
це T rue.
Просто змініть n & 1
на n & 2
2, яке представляє0010
в довічним і так далі.
Я пропоную використовувати шістнадцяткову нотацію, якщо ви новачок у бітових операціях
return n & 1;
>> return n & 0x01;
.