00001 #ifndef BIT_BASE_HH
00002 #define BIT_BASE_HH
00003
00004 #include <errno.h>
00005 #include <math.h>
00006 #include <assert.h>
00007 #include <vector>
00008 #include "bit/exceptions.hh"
00009
00010 namespace bit {
00011
00013 static const unsigned int max_bits_per_value = 32;
00014
00016 typedef unsigned int u32;
00017
00019 static const u32 max_u32 = (u32)-1;
00020
00022 typedef signed int s32;
00023
00025 static const s32 max_s32 = 0x7fffffff;
00026
00028 typedef unsigned long long u64;
00029
00031 typedef unsigned long long s64;
00032
00034 static const u64 max_u64 = (u64)-1;
00035
00037 static const unsigned int one_masks[] =
00038 { 0x00000000,
00039 0x00000001, 0x00000003, 0x00000007, 0x0000000f,
00040 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
00041 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
00042 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
00043 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
00044 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
00045 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
00046 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff };
00047
00049 static const int shift[] = { 0, 8, 16, 24, 32 };
00050
00054 inline u64 bytes_required(u64 num_elems, unsigned int bits_per_elem)
00055 {
00056 if (bits_per_elem > max_bits_per_value)
00057 throw bit::invalid_argument(
00058 "bit::bytes_required(): invalid bits_per_elem");
00059 return ((u64)num_elems * bits_per_elem + 7) / 8;
00060 }
00061
00063 inline unsigned int highest_bit(u64 value)
00064 {
00065 unsigned int ret = 0;
00066 while (value != 0) {
00067 ret++;
00068 value >>= 1;
00069 }
00070 return ret;
00071 }
00072
00074 inline unsigned int float2uint(float f)
00075 {
00076 union {
00077 float f;
00078 unsigned int i;
00079 } t;
00080 t.f = f;
00081 return t.i;
00082 }
00083
00085 inline float uint2float(unsigned int i)
00086 {
00087 union {
00088 float f;
00089 unsigned int i;
00090 } t;
00091 t.i = i;
00092 return t.f;
00093 }
00094
00103 inline float unquantize_float(u32 i, double step)
00104 {
00105 if (step == 0)
00106 return uint2float(i);
00107 unsigned int sign = i & 0x1;
00108 i >>= 1;
00109 float value = (double)i * step;
00110 if (sign)
00111 return -value;
00112 return value;
00113 }
00114
00124 inline u32 quantize_float(float f, double step)
00125 {
00126 if (step == 0)
00127 return float2uint(f);
00128 assert(step > 0);
00129 unsigned int sign = 0;
00130 if (f < 0) {
00131 sign = 1;
00132 f = -f;
00133 }
00134 double dvalue = (double)f / step;
00135 if (dvalue > max_s32)
00136 throw bit::invalid_argument("bit::quantize_float() result too large");
00137 u32 value = lrint(dvalue);
00138 return (value << 1) + sign;
00139 }
00140
00141 };
00142
00143 #endif