免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3191 | 回复: 8
打印 上一主题 下一主题

长整数除法器-望大家指导 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-07-17 09:25 |只看该作者 |倒序浏览
这是我写的一个支持很长字串的除法,在SCO和AIX上都跑过一些,不过肯定存在未发现的BUG,程序暂时没有加上注释,望大家先把它编译后运行,找出一些出错的数据反馈给我,谢谢,运行是命令+小数需要精确的位数
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char result[1024], szCs[1024];
long slen, si;

int main(int argc, char *argv[])
{
    char divdata1[1024], divdata2[1024];
    long len1, len2;
    int k, iRet, flag, s;

    si = len1 = len2 = flag = 0;

    if(argc < 2)
    {
        printf("请输入小数精确位数!Usage: commad 1\n");
        return -1;
    }

    memset(divdata1, 0x00, sizeof(divdata1));
    memset(divdata2, 0x00, sizeof(divdata2));
    memset(result, 0x00, sizeof(result));
    memset(szCs, 0x00, sizeof(szCs));

    printf("请输入除数:");
    scanf("%s", divdata1);
    strcpy(szCs, divdata1);
    printf("请输入被除数:");
    scanf("%s", divdata2);

    len1 = strlen(divdata1);
    slen = len1 - 1;
    len2 = strlen(divdata2);
    k = atoi(argv[1]);
    if(k != 0)
    {
        memset(divdata1+len1, '0', k);
        divdata1[len1+k] = '\0';
        len1 = strlen(divdata1);
        slen = len1 - 1;
        strcpy(szCs, divdata1);
    }

    if(isright(divdata1) != 0)
    {
        printf("请检查除数的合法性!\n");
        return 1;
    }

    if(isright(divdata2) != 0)
    {
        printf("请检查被除数的合法性!\n");
        return 1;
    }

    if(len2 > len1)
    {
        printf("运算结果=0\n");
        flag = 1;
    }
    else if(len2 == len1)
    {
        iRet = issame(divdata1, divdata2, len1);
        if(iRet == 0)
        {
            printf("运算结果=1\n");
            flag = 1;
        }
        else if(iRet == 1)
        {
            si = strlen(divdata1) - 1;
            procdiv(divdata1, divdata2, result);
        }
        else if(iRet == 2)
        {
            printf("运算结果=0\n");
            flag = 1;
        }
    }
    else
    {
        char szTmp[1024];
      
        memset(szTmp, 0x00, sizeof(szTmp));

        strncpy(szTmp, divdata1, len2);

        iRet = issame(szTmp, divdata2, len2);
        if(iRet == 1 || iRet == 0)
        {
            si = strlen(szTmp) - 1;
            procdiv(szTmp, divdata2, result);
        }
        else
        {
            memset(szTmp, 0x00, sizeof(szTmp));
            strncpy(szTmp, divdata1, len2+1);
            si = strlen(szTmp) - 1;
            procdiv(szTmp, divdata2, result);
        }
    }

    len1 = strlen(result);
/*
    change(0, len1-1, result);
*/
    if(flag == 0)
    {
        if(k != 0)
        {
            result[len1+1] = '\0';
            for(s = 0; s < k; s++)
            {
               result[len1] = result[len1-1];
               len1--;
            }
            result[len1] = '.';
        }
        printf("运算结果=%s\n", result);
    }

    return 0;
}

int change(long low, long high, char *databuf)
{
    char sztmp;

    if(low > high)
       return 0;

    sztmp = databuf[low];
    databuf[low] = databuf[high];
    databuf[high] = sztmp;

    change(low+1, high-1, databuf);
}

int issame(char *szbuf1, char *szbuf2, long len)
{
    long iret, i, j;

    i = j = 0;
   
    while(len > 0)
    {
        if(szbuf1 == szbuf2[j])
        {
           i++;
           j++;
           len--;
        }
        else if(szbuf1 > szbuf2[j])
           return 1;
        else
           return 2;
    }

    return 0;
}

int isright(char *szbuf)
{
    long i, len;

    i = 0;
    len = strlen(szbuf);

    while(len > 0)
    {
        if(szbuf[0] == '0')
            return 1;

        if(szbuf < '0' || szbuf > '9')
            return 1;

        i++;
        len--;
    }

    return 0;
}

int procdiv(char *szdata1, char *szdata2, char *result)
{
    long len1, len2, i, j, k;
    int sztag, data1, data2, iret, n, m;
    char szys[1024], szbuf[1024];

    memset(szys, 0x00, sizeof(szys));
    memset(szbuf, 0x00, sizeof(szbuf));
    i = j = k = sztag = 0;

/*
printf("si = [%d], slen = [%d], data1=[%s], data2=[%s]\n", si, slen, szdata1, szdata2);
*/
    if(si > slen)
        return 0;

    len1 = strlen(szdata1);
    len2 = strlen(szdata2);

    if(len1 < len2)
    {
        strcat(result, "0");
        strncat(szdata1, szCs+si+1, 1);
        si++;
        procdiv(szdata1, szdata2, result);
    }
    else if(len1 > len2)
    {
        len2 = strlen(szdata2);
        change(0, len2-1, szdata2);

        for(n = 9; n > 0; n--)
        {
            iret = funcmul(szdata1, szdata2, szbuf, n, &m);
            if(iret == 2)
            {
                char c[2];
                c[0] = m + '0';
                c[1] = '\0';
                strcat(result, c);
/*
printf("result = [%s]\n", result);
*/
                break;
            }
        }

        len1 = strlen(szdata1);
        change(0, len1-1, szdata1);
        len2 = strlen(szbuf);
        len1--;

/*
printf("data1 = [%s], data2 = [%s]\n", szdata1, szbuf);
*/
        while(len2 > 0)
        {
            data1 = szdata1-'0';
            data2 = szbuf[j]-'0';
            data1 = data1 - sztag;

            if(data1 == data2)
            {
                szys[k] = '0';
                i++;
                j++;
                k++;
                sztag = 0;
                len2--;
            }
            else if(data1 > data2)
            {
                int d;
                 
                d = data1 - data2;
                szys[k] = d + '0';
                i++;
                j++;
                k++;
                sztag = 0;
                len2--;
            }
            else
            {
                int d;
               
                d = data1 + 10 - data2;
                szys[k] = d + '0';
                i++;
                j++;
                k++;
                sztag = 1;
                len2--;
            }
        }
/***
        if(len1 != 0)
            sztag = szdata1[len1] - '0' - sztag;
***/
/*
printf("k11 = [%d], szys11 = [%s]\n", k, szys);
*/
        if(szys[k-1] == '0')
            pub_trim(szys);

/****
        if(sztag != 0)
        {
            szys[k] = sztag + '0';
            szys[k+1] = '\0';
        }
        else
*******/
        szys[k] = '\0';

        memset(szdata1, 0x00, sizeof(szdata1));
/*
printf("k = [%d], szys = [%s]  \n", k, szys);
*/
        strcpy(szdata1, szys);

        len1 = strlen(szdata1);
        change(0, len1-1, szdata1);
        len2 = strlen(szdata2);
        change(0, len2-1, szdata2);

        strncat(szdata1, szCs+si+1, 1);
        si++;
        procdiv(szdata1, szdata2, result);
    }
    else
    {
        iret = issame(szdata1, szdata2, len1);
        if(iret == 2)
        {
            strcat(result, "0");
            if(szdata1[0] == '0')
               memset(szdata1, 0x00, sizeof(szdata1));
            strncat(szdata1, szCs+si+1, 1);
            si++;
            procdiv(szdata1, szdata2, result);
            return 0;
        }
        else if(iret == 0)
        {
            strcat(result, "1");
            memset(szdata1, 0x00, sizeof(szdata1));
            strncat(szdata1, szCs+si+1, 1);
            si++;
            procdiv(szdata1, szdata2, result);
            return 0;
        }

        len2 = strlen(szdata2);
        change(0, len2-1, szdata2);

        for(n = 9; n > 0; n--)
        {
            iret = funcmul(szdata1, szdata2, szbuf, n, &m);
            if(iret == 2)
            {
                char c[2];
                c[0] = m + '0';
                c[1] = '\0';
                strcat(result, c);
/*
printf("result = [%s]\n", result);
*/
                break;
            }
        }

        len1 = strlen(szdata1);
        change(0, len1-1, szdata1);
        len2 = strlen(szbuf);
        len1--;

        while(len2 > 0)
        {
            data1 = szdata1-'0';
            data2 = szbuf[j]-'0';
            data1 = data1 - sztag;

            if(data1 == data2)
            {
                szys[k] = '0';
                i++;
                j++;
                k++;
                sztag = 0;
                len2--;
            }
            else if(data1 > data2)
            {
                int d;
                 
                d = data1 - data2;
                szys[k] = d + '0';
                i++;
                j++;
                k++;
                sztag = 0;
                len2--;
            }
            else
            {
                int d;
               
                d = data1 + 10 - data2;
                szys[k] = d + '0';
                i++;
                j++;
                k++;
                sztag = 1;
                len2--;
            }
        }

        szys[k] = '\0';
        if(szys[k-1] == '0')
           pub_trim(szys);
        memset(szdata1, 0x00, sizeof(szdata1));
/*
printf("szys = [%s]  ", szys);
*/
        strcpy(szdata1, szys);

        len1 = strlen(szdata1);
        change(0, len1-1, szdata1);
        len2 = strlen(szdata2);
        change(0, len2-1, szdata2);

        strncat(szdata1, szCs+si+1, 1);
/*
printf("iiiii szdata1 = [%s]\n", szdata1);
*/
        si++;
        procdiv(szdata1, szdata2, result);
    }

    return 0;
}

int funcmul(char *szdata1, char *szdata2, char *szbuf, int n, int *m)
{
    int sztag, i, j, d, iret;
    long len, len1;
    char sztmp[1024];

    memset(sztmp, 0x00, sizeof(sztmp));
    sztag = i = j = 0;
    len = strlen(szdata2);

    while(len > 0)
    {
        d = szdata2 - '0';
        d = d * n + sztag;
        if( d >= 10)
           sztag = d / 10;
        else
           sztag = 0;
  
        sztmp[j] = d - (d/10)*10 + '0';
        j++;
        i++;
        len--;
    }
   
    if(sztag != 0)
        sztmp[j] = sztag + '0';
    sztmp[j+1] = '\0';

/*
printf("sztmp = [%s], szdata2 = [%s]\n", sztmp, szdata2);
*/
    strcpy(szbuf, sztmp);
    len = strlen(szdata1);
    len1 = strlen(sztmp);
    if(len < len1)
        return 1;
    else if(len > len1)
    {
        *m = n;
        return 2;
    }

    change(0, len1-1, sztmp);
    iret = issame(szdata1, sztmp, len1);
    if(iret == 1 || iret == 0)
    {
        *m = n;
        return 2;
    }

    return 1;
}

int pub_trim(char *szbuf)
{
    long i, n, j;
   
    j = i = strlen(szbuf)-1;
    n = 0;


    while(i >= 0)
    {
        if(szbuf == '0')
            n++;
        else
            break;
        i--;
    }

    if(i < 0)
    {
        memset(szbuf, 0x00, sizeof(szbuf));
        return 0;
    }

    strncpy(szbuf, szbuf, j-n);
    szbuf[j-n+1] = '\0';

    return n;
}

论坛徽章:
0
2 [报告]
发表于 2007-07-17 09:49 |只看该作者
要是附件形式的就好了

论坛徽章:
0
3 [报告]
发表于 2007-07-17 09:58 |只看该作者
好,把附件上传

div.rar

2.04 KB, 下载次数: 38

论坛徽章:
38
2017金鸡报晓
日期:2017-02-08 10:39:4215-16赛季CBA联赛之深圳
日期:2023-02-16 14:39:0220周年集字徽章-年
日期:2022-08-31 14:25:28黑曼巴
日期:2022-08-17 18:57:0919周年集字徽章-年
日期:2022-04-25 13:02:5920周年集字徽章-20	
日期:2022-03-29 11:10:4620周年集字徽章-年
日期:2022-03-14 22:35:1820周年集字徽章-周	
日期:2022-03-09 12:51:3220周年集字徽章-年
日期:2022-02-10 13:13:4420周年集字徽章-周	
日期:2022-02-03 12:09:4420周年集字徽章-20	
日期:2022-01-25 20:14:2720周年集字徽章-周	
日期:2022-01-13 15:12:33
4 [报告]
发表于 2007-07-17 10:32 |只看该作者
这种练习题做什么测试啊,写完就完了,没有任何实用价值,别浪费时间了。

论坛徽章:
0
5 [报告]
发表于 2007-07-17 11:23 |只看该作者
各位有发现重大错误的吗?

论坛徽章:
0
6 [报告]
发表于 2007-07-17 11:32 |只看该作者
不说别的,你用scanf接受字符串就是一个大bug

原帖由 piao2004 于 2007-7-17 11:23 发表
各位有发现重大错误的吗?

论坛徽章:
0
7 [报告]
发表于 2007-07-17 11:35 |只看该作者
是的,如果输入足够大的话会越界,不过现在我更关心的是结果的正确性,以后可以改成动态分配的

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:49:45
8 [报告]
发表于 2007-07-17 13:53 |只看该作者
长整数最好用二进制位串来保存. 这样不仅简单而且速度快.

论坛徽章:
0
9 [报告]
发表于 2007-07-18 11:35 |只看该作者
更新版本

div.rar

2.04 KB, 下载次数: 41

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP