Określanie parzystości liczby

Często operacja modulo (wynikiem takiej operacji jest reszta z dzielenia) jest wykonywana na wartości 2. Pozwala to określić czy badana liczba jest parzysta.

Ostatnio uświadomiłem sobie, że sprawdzenie czy liczba jest parzysta można wykonać przez operację bitową. Wynika to z faktu że liczby nieparzyste posiadają pierwszy bit (od prawej strony) ustawiony na 1.

Pobawiłem się w badacza, napisałem program który wygląda tak (działa tylko na Windows):

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <Windows.h>
#include <limits.h>

#define NUMBER_TRIES 100000000L
#define ARRAY_SIZE 100
int a[ARRAY_SIZE];
int main()
{

unsigned int i,j,k=0;
unsigned long int start, end,delta,delta2;
time_t start2, end2;
/* Zapelnianie danymi tablicy*/
srand(time(NULL));
for(i=0;i<ARRAY_SIZE;i++)
a[i]=INT_MAX-rand();

/* Test operacji bitowej */
start=GetTickCount();
start2=time(NULL);
for(j=0;j<NUMBER_TRIES;j++)
for(i=0;i<ARRAY_SIZE;i++)
if((a[i] & 1)==1)
k=1;
else
k=0;
end2=time(NULL);
end=GetTickCount();
delta=end-start;
printf("Delta czasu dla operacji bitowej to: %un",delta);
printf("Delta czasu dla operacji bitowej to: %dn",(end2-start2));

/* Test operacji modulo */
start=GetTickCount();
start2=time(NULL);
for(j=0;j<NUMBER_TRIES;j++)
for(i=0;i<ARRAY_SIZE;i++)
if((a[i] % 2)==1)
k=1;
else
k=0;
end2=time(NULL);
end=GetTickCount();
delta2=end-start;
printf("Delta czasu dla operacji modulo to: %un",delta2);
printf("Delta czasu dla operacji modulo to: %dn",(end2-start2));

/*Interpretacja wynikow*/
printf("n");
if(delta>delta2)
printf("Operacja modulo jest szybsza od operacji bitowejn");
else
printf("Operacja bitowej jest szybsza od operacji modulon");
printf("wartosc absulutna roznicy delty: %dn",abs(delta-delta2));
return 0;
}

Kolejne etapy działania programu:

  1. Wypełnianie tablicy 100 (lub więcej zależy od ARRAY_SIZE) elementami, który mają pseudolosowy (bardzo pseudo) charakter. obliczany za pomocą INT_MAX – rand()
  2. Jednostką liczącą upływający czas pomiędzy dwoma okresami jest GetTickCount() funkcja znajdująca się w Windows.h (a konkretniej w winbase.h). Funkcja time() ma charakter sprawdzenia czy poprzednia dobrze działa.
  3. Potem wykonują się dwie zagnieżdżone pętle, zewnętrzna duża do wartości NUMBER_TIRES i wewnętrzna przechodząca po elementach tablicy.
  4. W zależności od parzystości, lub nie jest ustawiana 1 lub 0 w zmiennej k. Ma na celu przeciw działanie ewentualnej optymalizacji programu, która by usunęła pętlę skoro one nic nie robią.
Wyniki
Zakładałem że operacja bitowa będzie szybsza od modulo z powodu, że jest nie taka typowa dla tego zagadnienia :).
Jednak wyniki są takie (liczba prób 100000000, rozmiar tablicy 100) : 
  • Czas operacji bitowej to: 49920 milisekund (około 50 sekund)
  • Czas operacji modulo to: 48891 milisekund (około 49 sekund)
  • Różnica czasu to 1029 milisekund na korzyść operacji modulo (około 1 sekundy)