summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/main.cpp54
-rw-r--r--src/number.cpp54
-rw-r--r--src/number.h30
-rw-r--r--src/packedintarray.cpp137
-rw-r--r--src/packedintarray.h36
5 files changed, 311 insertions, 0 deletions
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 0000000..be49a1d
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,54 @@
1#include "number.h"
2#include "packedintarray.h"
3
4#include <bu/sio.h>
5using namespace Bu;
6
7void packedtest1()
8{
9 println("-==- Packed Int Test -==-");
10
11 PackedIntArray a(4);
12 a.append( 3 );
13 a.append( 9 );
14 a.append( 5 );
15
16 println("%1").arg( a.toString() );
17 println("%1").arg( a.toBitString() );
18 println("%1").arg( PackedIntArray(4, 10).toString() );
19
20 PackedIntArray b(5);
21 for( int j = 0; j < 16; j++ )
22 {
23 b.append( 21 );
24 if( b[j] != 21 )
25 {
26 println("Error at position %1").arg( j );
27 println("Raw: %1 (%2)").arg( b.toBitString() ).arg( b.toString() );
28 }
29 }
30}
31
32void numbertest1()
33{
34 println("-==- Number test -==-");
35
36 Number a("523");
37 Number b("498");
38
39 println("%1 + %2 = %3").
40 arg( a.toString() ).
41 arg( b.toString() ).
42 arg( (a + b).toString() );
43}
44
45int main( int argc, char *argv[] )
46{
47 println("CliC");
48
49 packedtest1();
50// numbertest1();
51
52 return 0;
53}
54
diff --git a/src/number.cpp b/src/number.cpp
new file mode 100644
index 0000000..e64be94
--- /dev/null
+++ b/src/number.cpp
@@ -0,0 +1,54 @@
1#include "number.h"
2
3#include <bu/sio.h>
4
5#define iRadix (10)
6
7Number::Number( int iOrd ) :
8 iOrd( iOrd ),
9 aInt( 4 )
10{
11}
12
13Number::Number( const Bu::String &sData, int iOrd ) :
14 iOrd( iOrd ),
15 aInt( 4 )
16{
17 for( int j = sData.getSize()-1; j >= 0; j-- )
18 aInt.append( sData[j]-'0' );
19}
20
21Number::~Number()
22{
23}
24
25Number Number::operator+( const Number &rhs ) const
26{
27 Number ret( iOrd );
28
29 int iPlaces = Bu::buMax(rhs.aInt.getSize(), aInt.getSize() )+1;
30
31 int iCarry = 0;
32 for( int j = 0; j < iPlaces; j++ )
33 {
34 int iRes = iCarry + digit( j ) + rhs.digit( j );
35 Bu::println(" Place: %1 + %2 + (%3) = %4").
36 arg( digit(j) ).arg( rhs.digit( j ) ).arg( iCarry )
37 .arg( iRes );
38 ret.aInt.append( (iRes%iRadix) );
39 if( iRes < iRadix )
40 iCarry = 0;
41 else
42 iCarry = iRes/iRadix;
43 }
44
45 return ret;
46}
47
48int Number::digit( int iOrder ) const
49{
50 if( iOrder >= aInt.getSize() )
51 return 0;
52 return aInt[iOrder];
53}
54
diff --git a/src/number.h b/src/number.h
new file mode 100644
index 0000000..4ada829
--- /dev/null
+++ b/src/number.h
@@ -0,0 +1,30 @@
1#ifndef NUMBER_H
2#define NUMBER_H
3
4#include <bu/string.h>
5#include "packedintarray.h"
6
7class Number
8{
9public:
10 Number( int iOrd=0 );
11 Number( const Bu::String &sData, int iOrd=0 );
12 virtual ~Number();
13
14 Number operator+( const Number &rhs ) const;
15
16 operator Bu::String() const
17 {
18 return aInt.toString();
19 }
20
21 Bu::String toString() const { return aInt.toString(); }
22
23 int digit( int iOrder ) const;
24
25private:
26 int iOrd;
27 PackedIntArray aInt;
28};
29
30#endif
diff --git a/src/packedintarray.cpp b/src/packedintarray.cpp
new file mode 100644
index 0000000..817a7ab
--- /dev/null
+++ b/src/packedintarray.cpp
@@ -0,0 +1,137 @@
1#include "packedintarray.h"
2
3#include <bu/sio.h>
4
5#define bitsizeof( x ) ((sizeof(x))*8)
6#define StoreBits ((bitsizeof(PackedIntArray::Store)))
7#define StoreCount( x ) (((x*iBitWidth)/StoreBits)+(((x*iBitWidth)%StoreBits)?1:0))
8
9PackedIntArray::PackedIntArray( PackedIntArray::Unit iBitWidth ) :
10 iBitWidth( iBitWidth ),
11 aData( NULL ),
12 iCapacity( 0 ),
13 iCount( 0 ),
14 uMask( 0 )
15{
16 aData = new Store[4];
17 iCapacity = (StoreBits*4)/iBitWidth;
18 if( iBitWidth < StoreBits )
19 {
20 if( (StoreBits%iBitWidth) == 0 )
21 iMaxSpan = 1;
22 else
23 {
24 iMaxSpan = (iBitWidth/StoreBits)+1;
25 }
26 }
27 for( int j = 0; j < iBitWidth; j++ )
28 uMask |= (1<<j);
29}
30
31PackedIntArray::PackedIntArray( PackedIntArray::Unit iBitWidth, int iCount ):
32 iBitWidth( iBitWidth ),
33 aData( NULL ),
34 iCapacity( StoreCount(iCount) ),
35 iCount( iCount ),
36 uMask( 0 )
37{
38 aData = new Store[StoreCount(iCapacity)];
39 memset( aData, 0, StoreCount(iCapacity));
40 for( int j = 0; j < iBitWidth; j++ )
41 uMask |= (1<<j);
42}
43
44PackedIntArray::~PackedIntArray()
45{
46 delete[] aData;
47}
48
49void PackedIntArray::append( PackedIntArray::Unit i )
50{
51 iCount++;
52 checkCapacity();
53 set( iCount-1, i );
54}
55
56PackedIntArray::Unit PackedIntArray::get( int idx ) const
57{
58 int iStore = idx*iBitWidth/StoreBits;
59 int iBit = (idx*iBitWidth)%StoreBits;
60// Bu::println("idx = %1, iStore = %2, iBit = %3").
61// arg( idx ).arg( iStore ).arg( iBit );
62
63 Unit ret = (aData[iStore]>>iBit)&uMask;
64
65 for( iBit = StoreBits-iBit; iBit < iBitWidth; )
66 {
67 iStore++;
68// Bu::println(" ==> iStore = %2, iBit = %3").
69// arg( idx ).arg( iStore ).arg( iBit );
70 ret |= (aData[iStore]&((Store)uMask)>>iBit)<<iBit;
71 iBit += StoreBits;
72 }
73 return ret;
74}
75
76PackedIntArray::Unit PackedIntArray::set( int idx, PackedIntArray::Unit i )
77{
78 int iStore = idx*iBitWidth/StoreBits;
79 int iBit = (idx*iBitWidth)%StoreBits;
80// Bu::println("idx = %1, iStore = %2, iBit = %3").
81// arg( idx ).arg( iStore ).arg( iBit );
82
83 aData[iStore] = (aData[iStore]& ~(((Store)uMask)<<iBit)) |
84 ((Store)i)<<iBit;
85 for( iBit = StoreBits-iBit; iBit < iBitWidth; )
86 {
87 iStore++;
88// Bu::println(" ==> iStore = %2, iBit = %3").
89// arg( idx ).arg( iStore ).arg( iBit );
90 aData[iStore] = (aData[iStore]& ~(((Store)uMask)>>iBit)) |
91 ((Store)i)>>iBit;
92 iBit += StoreBits;
93 }
94}
95
96Bu::String PackedIntArray::toBitString() const
97{
98 Bu::String sRet;
99 for( int j = iCount*iBitWidth-1; j >= 0; j-- )
100 {
101 sRet += (aData[j/StoreBits] & (1<<(j%StoreBits)))
102 ? "1" : "0";
103 if( j > 0 && j%iBitWidth == 0 )
104 sRet += " ";
105 }
106 return sRet;
107}
108
109Bu::String PackedIntArray::toString() const
110{
111 Bu::String sRet;
112 for( int j = iCount-1; j >= 0; j-- )
113 {
114 sRet += (char)(get(j))+'0';
115 }
116
117 return sRet;
118}
119
120void PackedIntArray::checkCapacity()
121{
122 if( iCount > iCapacity )
123 {
124 Bu::println("!!! Resizing !!!");
125 Store *aOldData = aData;
126 int iNewSize = StoreCount(iCapacity*2);
127 int iSize = StoreCount(iCapacity);
128 Bu::println(" %1 => %2 (%3 bit words)").arg( iSize ).arg( iNewSize )
129 .arg( StoreBits );
130 aData = new Store[iNewSize];
131 memset( aData, 0, iNewSize*sizeof(Store) );
132 memcpy( aData, aOldData, iSize*sizeof(Store) );
133 iCapacity *= 2;
134 delete[] aOldData;
135 }
136}
137
diff --git a/src/packedintarray.h b/src/packedintarray.h
new file mode 100644
index 0000000..953492b
--- /dev/null
+++ b/src/packedintarray.h
@@ -0,0 +1,36 @@
1#ifndef PACKED_INT_ARRAY_H
2#define PACKED_INT_ARRAY_H
3
4#include <bu/string.h>
5
6class PackedIntArray
7{
8public:
9 typedef uint_fast8_t Unit;
10 PackedIntArray( Unit iBitWidth );
11 PackedIntArray( Unit iBitWidth, int iCapacity );
12 virtual ~PackedIntArray();
13
14 void append( Unit i );
15 Unit operator[]( int idx ) const { return get( idx ); }
16 Unit get( int idx ) const;
17 Unit set( int idx, Unit i );
18 int getSize() const { return iCount; }
19
20 Bu::String toBitString() const;
21 Bu::String toString() const;
22
23private:
24 void checkCapacity();
25
26private:
27 typedef uint_fast32_t Store;
28 Unit iBitWidth;
29 Store *aData;
30 int iCapacity;
31 int iCount;
32 int iMaxSpan;
33 Unit uMask;
34};
35
36#endif