Strange bug...
Posted: Sat May 12, 2007 10:54 pm
I am having a very weird problem with this program I made..
My GetBit will for whatever reason only work properly in the bottom nibble..and I guess the SetBit only works at all in the bottom nibble...it is very weird..
here is my entire code..
unsigned_pint::GetBit, SetBit, and Add is what assumingly have the problems..
I tried to debug it, but GDB crashes when I get to the buggy code, so I have no idea...
here is my complete code(right now it's just one main.cpp file..)
My GetBit will for whatever reason only work properly in the bottom nibble..and I guess the SetBit only works at all in the bottom nibble...it is very weird..
here is my entire code..
unsigned_pint::GetBit, SetBit, and Add is what assumingly have the problems..
I tried to debug it, but GDB crashes when I get to the buggy code, so I have no idea...
here is my complete code(right now it's just one main.cpp file..)
Code: Select all
#include <iostream>
using namespace std;
#define DEFAULT_BITS 64
class unsigned_pint{
/**Private:**/
//this doesn't have anything advanced but the digit number...
unsigned int size;
unsigned int *bits; //a pointer to an array of unsigned ints...
public:
inline unsigned char GetBit(unsigned int bit);
inline unsigned char SetBit(unsigned int,unsigned char);
inline unsigned int GetSize();
unsigned_pint(unsigned int init_size,string init_value);
unsigned_pint(unsigned int init_size);
unsigned_pint();
~unsigned_pint();
int SetToValue(string source);
void Add(unsigned_pint* adder);
unsigned int tmp_get_first_int();
void tmp_set_first_int(unsigned int value);
};
// the init_size should be in bits..
//we count in BINARY!!
//This is how we add everything!
unsigned int unsigned_pint::tmp_get_first_int(){
return bits[0];
}
void unsigned_pint::tmp_set_first_int(unsigned int value){
bits[0]=value;
}
int unsigned_pint::SetToValue(string source){
cout <<"bah"<< endl;
return 0;
}
unsigned_pint::unsigned_pint(unsigned int init_size,string init_value){
size=init_size;
unsigned int tmp=init_size/sizeof(int);
if(tmp==0){tmp=4;}
if((tmp%4)!=0){tmp++;} //round off to the nearest int, with increase
bits=(unsigned int *)new char[tmp];
if(bits==NULL){exit(1);}
SetToValue(init_value);
}
unsigned_pint::unsigned_pint(unsigned int init_size){
}
unsigned_pint::unsigned_pint(){
}
unsigned_pint::~unsigned_pint(){
}
/**for whatever reason, it skips the carry of nibbles,
like 30 and 14 are added as the same number...it makes no sense
**/
void unsigned_pint::Add(unsigned_pint *adder){
volatile unsigned char carry=0;
unsigned int current_bit=0;
unsigned int limit;
if(adder->GetSize()>this->GetSize()){
limit=this->GetSize();
}else{
limit=adder->GetSize();
}
unsigned char tmp;
for(current_bit=0;current_bit<limit;current_bit++){
tmp=(char)(carry<<2)|((char)adder->GetBit(current_bit)<<1)|((char)this->GetBit(current_bit));
if((adder->GetBit(current_bit)==0xFF) || (this->GetBit(current_bit)==0xFF)){
printf("overflow!\n");
exit(1);
}
//the format of tmp is now carry|op|target|
printf("value: %i | %i | %i \n",(int)carry,(int)adder->GetBit(current_bit),(int)GetBit(current_bit));
printf("tmp: %i\n",tmp);
printf("bits0: %i\n",bits[0]);
cout << "bit: " << current_bit << endl;
switch(tmp){
case 0: //000
//do nothing...with no carray or any bits set, we just leave it as 0
break;
case 2: //010
case 1: //001
SetBit(current_bit,1);
break;
case 3: //011
SetBit(current_bit,0);
carry=1;
break;
case 4: //100
carry=0;
SetBit(current_bit,1);
break;
case 7: //111
carry=1;
SetBit(current_bit,1);
break;
case 5: //101
case 6: //110
carry=1;
SetBit(current_bit,0);
} //really, that's it!
}
}
inline unsigned char unsigned_pint::GetBit(unsigned int bitn){
unsigned int array_index,bit_index;
if(bitn>size){return 0xFF;} //if we request a bit higher than the size...
array_index=bitn/sizeof(int);
bit_index=bitn%sizeof(int);
unsigned int tmp;
tmp=bits[array_index];
tmp=tmp&(1<<bit_index);
if(tmp>=1){
return 1;
}else{
return 0;
}
}
inline unsigned char unsigned_pint::SetBit(unsigned int bitn,unsigned char value){
unsigned int array_index,bit_index;
if(bitn>size){return 0xFF;} //if we request a bit higher than the size...
array_index=bitn/sizeof(int);
bit_index=bitn%sizeof(int);
unsigned int tmp_return=GetBit(bitn);
if(value>=1){
bits[array_index]=bits[array_index] | (1<<bit_index);
}else{
bits[array_index]=bits[array_index] & (unsigned int)(-1^(1<<bit_index));
//here we use -1 as -1 will always be the highest possible number, which means all bits will be set
}
return tmp_return;
}
inline unsigned int unsigned_pint::GetSize(){
return size;
}
int main(){
unsigned_pint test(32,"28");
unsigned_pint t2(32,"0");
t2.tmp_set_first_int(1); //14 and 30 are considered the same!
printf("t2: %i\n",(unsigned int)t2.tmp_get_first_int());
test.tmp_set_first_int(30); //but here, if you set this to 30 or 14 it is properly recognized!
test.Add(&t2);
printf("test_value: %i\n",(int)test.tmp_get_first_int());
cout << "Hello world!" << std::endl;
return 0;
}
/***Just for a bit of reference, this is the truth table of adding
C=carry
___________________________
Car op1 op2 result
0 0 0 0
0 1 1 0+C
0 1 0 1
0 0 1 1
1 0 0 1
1 1 1 1+C
1 0 1 0+C
1 1 0 0+C
___________________________
**/