1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
| #include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <limits.h>
#define ARRAYSIZE 1000000
unsigned int number[ARRAYSIZE];
/****************************************************************************
Solution de fearyourself
****************************************************************************/
unsigned int pow2sup(unsigned int nbr)
{
int bs,bi;
int min = 0;
int max = 31;
int mid = (min + max)/2;
/* Borne inferieure */
if(nbr <= 1) {
return 1;
}
/* Borne superieure */
if( nbr > (1<<30)) {
return (1<<31);
}
do
{
bs = (1<<mid);
bi = (1<<(mid-1));
if(nbr < bi) {
max = mid;
mid = (min+max)/2;
}
else {
if(nbr > bs) {
min = mid;
mid = (min+max)/2;
}
else {
if(bi == nbr) {
return bi;
}
return bs;
}
}
}while(min != max);
return 0;
}
/****************************************************************************
Solution de Jean-Marc Bourguet
****************************************************************************/
unsigned int pwrf(unsigned int n)
{
unsigned long pwr = ~(((unsigned long)-1)>>1);
#if ULONG_MAX / (1U<<16) > (1U<<16)
#if ULONG_MAX / (1U<<32) > (1U<<32)
if (n <= (pwr >> 64)) { pwr >>= 64; }
#endif
if (n <= (pwr >> 32)) { pwr >>= 32; }
#endif
if (n <= (pwr >> 16)) { pwr >>= 16; }
if (n <= (pwr >> 8)) { pwr >>= 8; }
if (n <= (pwr >> 4)) { pwr >>= 4; }
if (n <= (pwr >> 2)) { pwr >>= 2; }
if (n <= (pwr >> 1)) { pwr >>= 1; }
return pwr;
}
/****************************************************************************
Solution de stephl
****************************************************************************/
unsigned int power2sup(unsigned int i)
{
unsigned int power;
for (power=1;power<i;power<<=1);
return power;
}
/****************************************************************************
Test
****************************************************************************/
void doit(int nbval,int ntimes,unsigned int (*func)(unsigned int),
char *methodname)
{
unsigned int starttime,duration,res;
int i,j;
for (j=0,starttime=GetTickCount();j<ntimes;++j)
for (i=0;i<nbval;++i)
{
res=(*func)(number[i]);
#ifdef OUTPUT
printf("n=%u\tres=%u\n",number[i],res);
#endif
}
duration=GetTickCount()-starttime;
printf("Méthode %s: %.3f s\n",methodname,(double) duration/1000.0);
}
/****************************************************************************
main
Paramètres optionnels pour l'appel du programme: [NB_FOIS] [NB_VALEURS]
****************************************************************************/
#define MAXPOW2 (1U<<((sizeof (int)<<3)-1))
int main(int argc,char **argv)
{
int nbval,i,ntimes;
if (argc<3 || (nbval=atoi(argv[2]))>ARRAYSIZE) nbval=ARRAYSIZE;
if (argc==1) ntimes=1;
else ntimes=atoi(argv[1]);
srand(GetTickCount());
for (i=0;i<nbval;++i) number[i]=rand()%(MAXPOW2+1);
doit(nbval,ntimes,pow2sup,"fearyourself");
doit(nbval,ntimes,pwrf,"Jean-Marc Bourguet");
doit(nbval,ntimes,power2sup,"stephl");
return 0;
} |
Partager