-
BCD operations
I have written a function that converts a double to a BCD (BCD: Save each digit of the double as an unsigned char, in addition save the complete length, the fractional length (part behind the floating point) and the sign of the double number). I use the following struct
Code:
struct bcd_number
{
unsigned int length;
unsigned int fractional;
signed char sign;
unsigned char *digits;
};
And thats the double to BCD function:
Code:
struct bcd_number* double2bcd(double x)
{
char tmp[512];
struct bcd_number* bcd = malloc (sizeof(struct bcd_number));
int a = x;
double before = a;
double fractional;
fractional = x-(long)x;
bcd->digits = malloc (512);
char* z = (char*) bcd->digits;
sprintf (tmp,"%g",fabs(before));
bcd->length = strlen(tmp);
bcd->sign = (before < 0) ? '-' : '+';
for (size_t i=0; i<bcd->length; ++i)
{ *z++ = tmp[i] - '0'; }
sprintf (tmp,"%g",fabs(fractional));
for (size_t i = strlen(tmp)-1; i!=0; --i)
if (tmp[i] != '0')
{ tmp[i+1] = 0; break; }
bcd->fractional = strlen(tmp+2);
bcd->length += bcd->fractional;
for (char* t = tmp + 2; *t; *z++ = *t++ - '0');
bcd->digits = realloc (bcd->digits, bcd->length);
return bcd;
}
That works perfect.
And I had also added the ability to preform addition/subtraction (Complete source code: [C] BCD - Pastebin.com) but now I want to preform multiplication and division. But the problem is that there are only chars as digits (I dont want to change that). I now that must be like 'multiplication on the paper' (classical way without calculator) but I have the idea that it must be like addition with the modulo operator. On the other hand I have no idea how to implement it with chars with modulo. Any ideas or hints?
-
You do it the way you were taught at primary school.
You need a 10x10 multiplication table, giving all the combinations of '0'-'9' and '0'-'9'. When there's an overflow, which will be most of the time with multiplication, you need to carry the most significant digits. So you also need a 10x10 addition table to add the carrys. And remember you might need to carry the carries.
Of course you don't have to code in the tables explicitly because the computer can work them out. But I'd advise doing so on the first attempt, to get the logic right.
The floating point isn't a problem, since if you have n and m digits after the decimal point, you always have m + n digits in the result. So you can just ignore the ploint and then put it in at the last step. However numbers will quickly get very long if you insist on never losing precision.
-
I notice several bugs here already:
Lines 7 and 8 are destroying anything outside the range of an int. Should use before = floor(x);
Line 10 need to use the floor function here again (or the result from above), otherwise it fails for double values outside the range of a long: fractional = x - before;
Lines 23 and 34 should not be using %g as the format specifier. You actually want %f.
Line 51: You shouldn't call realloc in a loop like that.
It doesn't handle NANs and infinities, but I guess you're aware of that.
Is this a hobby project, or some kind of assignment?
-
It looks like the OP is receiving all the help they need on their cross-post.
-
why do people do that crap...mass post the same question on multiple sites??? WITHOUT even waiting for an answer......stupid kiddies....
that is why i miss the older days were tracing an ip to the front door was easier to do...keyboard tough guy was the guy beating you over the head with your keyboard 20 minutes after you post something stupid!!!
(also miss the days where you could track by SS#, License plate, etc LONG before identity theft was "public". The days before Kevin M. had his job as a "security consultant")