[开心IT面试题] C实现大整数四则运算

由于经常要处理一些大数据的运算,用整型不够,所以用c语言实现了大整数四则运算。

废话就不多说,直接贴代码,代码中有注释。

 

#define BIT_TOTAL 500
typedef struct{
    char BigInt[BIT_TOTAL];
    bool isNegative;
}BIGINT;

void Reverse(char nData[])
{
    char temp;
    for (int i = 0, j = strlen(nData)-1; (i != j) && (i - j != 1); i++, j--)
    {
        temp = nData[i];
        nData[i] = nData[j];
        nData[j] = temp;
    }
}

BIGINT Add(BIGINT first, BIGINT second)
{
    BIGINT result;
    memset(&result, 0, sizeof(BIGINT));

    if(first.isNegative)
    {
        if(second.isNegative)
        {
            result.isNegative = 1;
            first.isNegative = 0;
            second.isNegative = 0;
            strcpy(result.BigInt, Add(first, second).BigInt);
            return result;
        }else
        {
            first.isNegative = 0;
            return Minus(second, first);
        }
    }else
    {
        if(second.isNegative)
        {
            second.isNegative = 0;
            return Minus(first, second);
        }
    }

    Reverse(first.BigInt);
    Reverse(second.BigInt);

    int temp = 0;
    int bit = 0;
    int length = strlen(first.BigInt) > strlen(second.BigInt) ? strlen(first.BigInt):strlen(second.BigInt);
    for (int i = 0; i < length; i++)
    {
        if(first.BigInt[i] == '\0')
        {
            first.BigInt[i] = '0';
        }
        if(second.BigInt[i] == '\0')
        {
            second.BigInt[i] = '0';
        }
        temp = (first.BigInt[i]-'0') + (second.BigInt[i]-'0') + bit;
        if (temp >= 10)
        {//有进位
            temp = temp % 10;
            bit = 1;
        }else
        {//无进位
            bit = 0;
        }
        result.BigInt[strlen(result.BigInt)] = char(temp + '0');
    }
    //判断是否要在最高位加一位数
    if (bit == 1)
    {
        result.BigInt[strlen(result.BigInt)] = char(bit + '0');
    }
    Reverse(result.BigInt);
    return result;
}

BIGINT Minus(BIGINT first, BIGINT second)
{
    BIGINT result;
    memset(&result, 0, sizeof(BIGINT));

    if(first.isNegative)
    {
        if(second.isNegative)
        {
            first.isNegative = 0;
            second.isNegative = 0;
            return Minus(second, first);
        }else
        {
            result.isNegative = 1;
            first.isNegative = 0;
            strcpy(result.BigInt, Add(first, second).BigInt);
            return result;
        }
    }else
    {
        if(second.isNegative)
        {
            second.isNegative = 0;
            return Add(first, second);
        }
    }
    if(strlen(first.BigInt) < strlen(second.BigInt))
    {
        result.isNegative = 1;
        strcpy(result.BigInt, Minus(second, first).BigInt);
        return result;
    }else if(strlen(first.BigInt) == strlen(second.BigInt))
    {
        if(strcmp(first.BigInt, second.BigInt) < 0)
        {
            result.isNegative = 1;
            strcpy(result.BigInt, Minus(second, first).BigInt);
            return result;
        }
        if(strcmp(first.BigInt, second.BigInt) == 0)
        {
            result.isNegative = 0;
            result.BigInt[0] = '0';
            return result;
        }
    }

    Reverse(first.BigInt);
    Reverse(second.BigInt);

	int temp = 0;
    int bit = 0;
    for (int i = 0; i < strlen(first.BigInt); i++)
    {
        if(second.BigInt[i] == '\0')
        {
            second.BigInt[i] = '0';
        }
        temp = (first.BigInt[i]-'0') - (second.BigInt[i]-'0') - bit;
		if (temp < 0)
		{//有借位
            temp = 10 + (first.BigInt[i]-'0') - (second.BigInt[i]-'0') - bit;
			bit = 1;
		}else
		{//无借位
			bit = 0;
		}
        if(temp >= 0)
        {
            result.BigInt[strlen(result.BigInt)] = char(temp + '0');
		}
    }
    //将头为零的部分去掉
    while(result.BigInt[strlen(result.BigInt)-1] == '0')
    {
        result.BigInt[strlen(result.BigInt)-1] = '\0';
    }
    Reverse(result.BigInt);

    return result;
}

BIGINT Multiply(BIGINT first, BIGINT second)
{
    BIGINT result;
    memset(&result, 0, sizeof(BIGINT));
    if((first.isNegative * second.isNegative != 0))
    {
        result.isNegative = 1;
    }

    BIGINT tempResult;
    memset(&tempResult,0,sizeof(BIGINT));
    BIGINT tempCountInfo;

	//第二个数据的每位分别乘以第一个数据,然后求和
    //tempResult.BigInt存放前面所有的结果值的和
    //tempCountInfo.BigInt存放该位乘以第一个数据的结果值
    for (int j = strlen(second.BigInt)-1; j >= 0; j--)
	{
        int bit = 0;
        int temp = 0;
        memset(&tempCountInfo,0,sizeof(BIGINT));

        //第二个数据的j位乘以第一个数据的值在后面加strlen(second.BigInt)-1-j个0,
        //所以结果值从tempCountInfo.BigInt[strlen(second.BigInt)-1-j]开始放
        memset(tempCountInfo.BigInt, '0', (strlen(second.BigInt)-1-j));
        for (int i = strlen(first.BigInt)-1; i >= 0; i--)
		{
            temp = (first.BigInt[i]-'0') * (second.BigInt[j]-'0') + bit;
            if (temp >= 10)
			{//有进位
				bit = temp / 10;
				temp = temp % 10;
			}else
			{//无进位
				bit = 0;
			}
            tempCountInfo.BigInt[strlen(tempCountInfo.BigInt)] = char(temp+'0');
		}
		if (bit != 0)
		{
            tempCountInfo.BigInt[strlen(tempCountInfo.BigInt)] = char(bit+'0');
		}

        Reverse(tempCountInfo.BigInt);
        //该位乘运算的值与前面所有的和进行求和
        tempResult = Add(tempResult, tempCountInfo);
	}
    strcpy(result.BigInt, tempResult.BigInt);
    return result;
}

BIGINT Division(BIGINT first, BIGINT second)
{
    BIGINT result;
    memset(&result, 0, sizeof(BIGINT));
    if (second.BigInt[0] == 0)
    {
        return result;
    }
    //判断商正负数
    if((first.isNegative * second.isNegative != 0))
    {
        result.isNegative = 1;
        first.isNegative = 0;
        second.isNegative = 0;
    }

    //当除数大于被除数时,商等于0;当除数等于被除数时,商等于1.
    if(strlen(first.BigInt) < strlen(second.BigInt))
    {
        result.BigInt[0] = 0;
        return result;
    }else if(strlen(first.BigInt) == strlen(second.BigInt))
    {
        if(strcmp(first.BigInt, second.BigInt) < 0)
        {
            result.BigInt[0] = 0;
            return result;
        }else if(strcmp(first.BigInt, second.BigInt) < 0)
        {
            result.BigInt[0] = 1;
            return result;
        }
    }

    //临时被除数
    BIGINT tempDividend;
    //当前计算到被除数的第几位
    int dividendBit = 0;
    //临时存放中间变量
    BIGINT tempCountInfo;
    memset(&tempDividend, 0, sizeof(BIGINT));
    memset(&tempCountInfo, 0, sizeof(BIGINT));

    //备份除数的长度和第一位值
    int divisorLen = strlen(second.BigInt);
    int divisorFirstBit = second.BigInt[0];
    //首先先将商全部置成0
    memset(result.BigInt, '0', strlen(first.BigInt)*sizeof(char));

    do
    {
        //将被除数的相应位放进tempDividend.BigInt中
        //提取这次要运算的被除数的数据
        while(strlen(tempDividend.BigInt) < strlen(second.BigInt))
        {
            tempDividend.BigInt[strlen(tempDividend.BigInt)] = first.BigInt[dividendBit];
            dividendBit++;
            if(dividendBit >= strlen(first.BigInt))
            {
                break;
            }
        }
        if(dividendBit >= strlen(first.BigInt))
        {
            if (strlen(tempDividend.BigInt) < divisorLen)
            {
                break;
            }else if (strlen(tempDividend.BigInt) == divisorLen)
            {
                if(strcmp(tempDividend.BigInt, second.BigInt) < 0)
                {
                    break;
                }
            }
        }
        if((strlen(tempDividend.BigInt) == divisorLen) && (strcmp(tempDividend.BigInt, second.BigInt) < 0))
        {
            tempDividend.BigInt[strlen(tempDividend.BigInt)] = first.BigInt[dividendBit];
            dividendBit++;
        }
        if(dividendBit >= strlen(first.BigInt))
        {
            if (strlen(tempDividend.BigInt) < divisorLen)
            {
                break;
            }else if (strlen(tempDividend.BigInt) == divisorLen)
            {
                if(strcmp(tempDividend.BigInt, second.BigInt) < 0)
                {
                    break;
                }
            }
        }

        int multiple = 1;
        if (strlen(tempDividend.BigInt) == divisorLen)
        {
            if ((tempDividend.BigInt[0]-'0') / (divisorFirstBit-'0') > 3)
            {
                multiple = (tempDividend.BigInt[0]-'0') / (divisorFirstBit-'0') - 1;
            }
        }else if (strlen(tempDividend.BigInt) > divisorLen)
        {
            int temp = (tempDividend.BigInt[0]-'0') * 10 + (tempDividend.BigInt[1]-'0');
            if (temp / (divisorFirstBit-'0') > 2)
            {
                multiple = temp / (divisorFirstBit-'0') - 1;
            }
        }

        //求出除数在tempDividend.BigInt内最大倍数
        int j = 0;
        for (j = multiple; j < 10; j++)
        {
            memset(&tempCountInfo, 0, sizeof(BIGINT));
            tempCountInfo.BigInt[0] = j+'0';
            memcpy(&tempCountInfo, &Multiply(second, tempCountInfo), sizeof(BIGINT));

            //计算该倍数的结果与该次的被除数之间的余数
            memcpy(&tempCountInfo, &Minus(tempDividend, tempCountInfo), sizeof(BIGINT));

            if (strlen(tempCountInfo.BigInt) < divisorLen)
            {
                break;
            }else if (strlen(tempCountInfo.BigInt) == divisorLen)
            {
                if(strcmp(tempCountInfo.BigInt, second.BigInt) < 0)
                {
                    break;
                }
            }
        }
        result.BigInt[dividendBit-1] = j+'0';
        memcpy(tempDividend.BigInt, tempCountInfo.BigInt, strlen(tempDividend.BigInt)*sizeof(char));
        tempDividend.BigInt[strlen(tempDividend.BigInt)] = first.BigInt[dividendBit];
        dividendBit++;
        if(dividendBit >= strlen(first.BigInt))
        {
            if (strlen(tempDividend.BigInt) < divisorLen)
            {
                break;
            }else if (strlen(tempDividend.BigInt) == divisorLen)
            {
                if(strcmp(tempDividend.BigInt, second.BigInt) < 0)
                {
                    break;
                }
            }
        }
    }while(1);

    //将头为零的部分去掉
    Reverse(result.BigInt);
    while(result.BigInt[strlen(result.BigInt)-1] == '0')
    {
        result.BigInt[strlen(result.BigInt)-1] = '\0';
    }
    Reverse(result.BigInt);

    return result;
}


 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值