Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

fibonacci.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002     fibonacci.cpp  -  Definition of Fibonacci class methods.
00003                              -------------------
00004     begin                : October 23 2002
00005     copyright            : (C) 2003 by Vojtìch Toman
00006     email                : vtoman@lit.cz
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00026 #include "fibonacci.h"
00027 
00028 
00029 #ifdef __GNUG__
00030 # pragma implementation
00031 #endif
00032 
00033 
00034 //  Generated list of Fibonacci numbers of order 4 (first number omitted).
00035 //  Unused.
00036 //  static unsigned long Order4FibonacciNumbers_[] = {
00037 //    /*1,*/ 1, 4, 7, 13,
00038 //    25, 49, 94, 181, 349,
00039 //    673, 1297, 2500, 4819, 9289,
00040 //    17905, 34513, 66526, 128233, 247177,
00041 //    476449, 918385, 1770244, 3412255, 6577333,
00042 //    12678217, 24438049, 47105854, 90799453, 175021573,
00043 //    337364929, 650291809
00044 //  };
00045 
00046 //  Number of generated Fibonacci numbers of order 4.
00047 //  #define NUMBER_OF_ORDER4_FIBS               31
00048 
00049 
00051 static unsigned long Order2FibonacciNumbers_[] = {
00052   1, 2, 3, 5,
00053   8, 13, 21, 34, 55,
00054   89, 144, 233, 377, 610,
00055   987, 1597, 2584, 4181, 6765,
00056   10946, 17711, 28657, 46368, 75025,
00057   121393, 196418, 317811, 514229, 832040,
00058   1346269, 2178309, 3524578, 5702887, 9227465,
00059   14930352, 24157817, 39088169, 63245986, 102334155,
00060   165580141, 267914296, 433494437, 701408733, 1134903170
00061 };
00062 
00064 #define NUMBER_OF_ORDER2_FIBS           44
00065 
00066 
00075 unsigned long Fibonacci::encode(unsigned long number)
00076 {
00077   int i = NUMBER_OF_ORDER2_FIBS - 1;
00078 
00079   unsigned long fn;
00080   unsigned long code;
00081   
00082   code = 1;
00083 
00084   while (i > -1)
00085     {
00086       fn = Order2FibonacciNumbers_[i];
00087 
00088       if (fn <= number)
00089         {
00090           number -= fn;
00091           
00092           code <<= 1;
00093           code |= 1;
00094         }
00095       else
00096         if (code > 1)
00097           code <<= 1;
00098 
00099       i--;
00100     }
00101 
00102   return code;
00103 }
00104 
00105 
00106 
00115 unsigned long Fibonacci::decode(unsigned long code)
00116 {
00117   unsigned long number = 0;
00118   int i = 0;
00119   bool lastWasOne = false;
00120   
00121   while (code)
00122     {
00123       if (code & 1)
00124         {
00125           if (!lastWasOne)
00126             {
00127               number += Order2FibonacciNumbers_[i];
00128 
00129               lastWasOne = true;
00130             }
00131           else
00132             //two 11 appeared --> code ended
00133             return number;
00134         }
00135       else
00136         lastWasOne = false;
00137       
00138       code >>= 1;
00139       i++;
00140     }
00141 
00142   return number;
00143 }
00144 
00145 
00146 
00160 size_t Fibonacci::encodeToBuffer(void *buffer, size_t itemSize, unsigned long number)
00161 {
00162   unsigned char *charBuf = (unsigned char *)buffer;
00163   unsigned char tmpChar = 0;
00164   unsigned char bits = 0;
00165   size_t charsTotal = 0;
00166   unsigned long code = encode(number);
00167 
00168 
00169   while (code)
00170     {
00171       tmpChar <<= 1;
00172       tmpChar |= (code & 1);
00173       bits++;
00174 
00175       if (bits == SIZEOF_CHAR*8)
00176         {
00177           //store char to the buffer
00178           charBuf[charsTotal] = tmpChar;
00179           charsTotal++;
00180           bits = 0;
00181           tmpChar = 0;
00182         }
00183 
00184       code >>= 1;
00185     }
00186 
00187   if (!bits)
00188     //exactly n bytes
00189     charsTotal--;
00190   else
00191     {
00192       //output the last "partial" char
00193       //"align it to the left"
00194       while (bits < SIZEOF_CHAR*8)
00195       {
00196         tmpChar <<= 1;
00197         bits++;
00198       }
00199       charBuf[charsTotal] = tmpChar;
00200     }
00201 
00202 
00203   while ((charsTotal + 1) % itemSize)
00204     {
00205       //add fill chars if needed
00206       charsTotal++;
00207       charBuf[charsTotal] = 0;
00208     }
00209 
00210   return (charsTotal+1) / itemSize;
00211 }
00212 
00213 
00214 
00215 
00229 size_t Fibonacci::decodeFromBuffer(void *buffer, size_t itemSize, size_t *nrItems)
00230 {
00231   unsigned long code = 0;
00232   unsigned long number;
00233   unsigned char *charBuf = (unsigned char *)buffer;
00234   bool lastWasOne = false;
00235   unsigned char tmpChar = 0;
00236   size_t charsTotal = 0;
00237   unsigned char mask;
00238 
00239 
00240   while (true)
00241     {
00242       tmpChar = charBuf[charsTotal];
00243       charsTotal++;
00244       mask = 1 << (SIZEOF_CHAR*8-1);
00245 
00246       while (mask)
00247         {
00248           if (tmpChar & mask)
00249             {
00250               if (!lastWasOne)
00251                 {
00252                   code <<= 1;
00253                   code |= 1;
00254                   lastWasOne = true;
00255                 }
00256               else
00257                 {
00258                   number = decode(code);
00259 
00260                   while (charsTotal % itemSize)
00261                     charsTotal++;
00262                   
00263                   *nrItems = charsTotal / itemSize;
00264                   return number;
00265                 }
00266             }
00267           else
00268             {
00269               code <<= 1;
00270               lastWasOne = false;
00271             }
00272 
00273           mask >>= 1;
00274         }
00275     }
00276 
00277 }
00278 
00279 

Generated on Wed Feb 5 10:43:01 2003 for Exalt by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002