2013-01-02 148 views
1

我写了一个将double转换为BCD的函数(BCD:将double的每个数字保存为无符号字符,另外还保存了完整的长度,分数长度(浮点后面的部分)和双号的符号)。 我用下面的结构BCD算术运算

struct bcd_number 
{ 
unsigned int length; 
unsigned int fractional; 
signed char sign; 
unsigned char *digits; 
}; 

并且那双到BCD功能:

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; 
} 

这完美的作品。

而且我还添加了预成型加/减的功能(完整的源代码:http://pastebin.com/HR70VukM),但现在我想要进行乘法和除法。 但问题是,只有字符作为数字(我不想改变)。我现在必须像'纸上的乘法'(没有计算器的经典方法),但我有这样的想法,它必须像模运算符一样加法运算。另一方面,我不知道如何用模以字符来实现它。任何想法或提示?

+0

你真的应该删除最初的'malloc()'。一旦知道了正确的大小,就可以转换为函数中的临时缓冲区,然后转换为'malloc()',而不需要'realloc()'。更好的是,决定最大静态尺寸并始终使用该尺寸,因为您还要存储长度。许多小的(10-30字节)分配可能非常昂贵并且无法管理。 – unwind

+0

具体问题是什么并不是很清楚。如果你问“如何用十进制执行[长乘法](http://en.wikipedia.org/wiki/Long_multiplication#Long_multiplication)?”,那么答案是“你可以用手做同样的事情” 。 –

+0

好吧我想写一个函数(例如:struct bcd_number * multiplication(struct bcd_number * a,struct bcd_number * b),它预处理了乘法,但是我遇到了“同样的问题”手“的方式 – Kossi

回答

0

乘法和除法后是什么?阶乘?模?指数?自然对数?正弦?余弦? 把BCD变成双打,做任何数学运算,把结果转换成BCD

0

你想知道关于BCD的所有信息都可以在网站General Decimal Arithmetic找到。

对于乘法,您需要一个原始程序,将两个数字相乘得到两位数结果。将此中间结果添加到答案中的适当位置。除了有一个“乘法表”之外,找到这个“合适的位置”是“你可以用手工完成”的方法的关键。