C语言四则运算大数计算(单头文件库)

这个博客介绍了一个C语言实现的超大数算法库,包括加法、减法、乘法和除法。代码实现了大数的加减乘除运算,并且提供了大数除法的高精度实现。通过示例展示了如何使用这些算法进行大数运算,适用于需要处理大数的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

整数浮点数通用大数精确算法
除法精度1000
加减乘除法大数算法单头文件库。

具体用法看源文件中的调用以及解释。

源文件

#include<stdio.h>

#define WGX_MATH_CALC_IMPLEMENTATION
#include"wgx_math_calc.h"
int main(int argc, char** argv){
    char res[20000];
    char s1[10000];
    char s2[10000];
    char *p=NULL;
    printf("输入被除数:\n");
    scanf("%9999s",s1);
    printf("\n\n");
    printf("输入除数:\n");
    scanf("%9999s",s2);
    //注意下面参数这个500是精度,必须为正整数
    p=wgx_div(s1,s2,1000);
    printf("\n\n%s\n除以\n%s\n=\n%s",s1,s2,p);
    free(p);
    return 0;
}

下面是头文件
wgx_math_calc.h

// wgx_math_calc.h文件
// 加减乘除超大数计算
#ifndef INCLUDE_WGX_MATH_CALC_H
#define INCLUDE_WGX_MATH_CALC_H
#ifdef  __cplusplus
extern "C"
{
#endif
	// 字符串形式比较两个数大小
	extern int s1_compare_s2(char *s1, char *s2);
	// 求正整数的倒数
	extern char *daoshu(char *fenmu, unsigned int maxlen);
	// 去掉无效0,用完记得释放指针
	extern char *delInvalidZeros(char *str);
	// 大数加法算法
	extern char *wgx_add(char *s1, char *s2);
	// 大数减法算法
	extern char *wgx_sub(char *s1, char *s2);
	// 大数乘法算法
	extern char *wgx_mcl(char *s1, char *s2);
	// 大数除法算法
	extern char *wgx_div(char *s1, char *s2, unsigned int maxlen);

	// 大数阶乘算法
	// m的n次方算法
#ifdef   __cplusplus
}
#endif

#ifdef WGX_MATH_CALC_IMPLEMENTATION
#ifndef   STDIO_H
#include<stdio.h>
#endif
#ifndef   STDLIB_H
#include<stdlib.h>
#endif
#ifndef   STRING_H
#include<string.h>
#endif
#ifndef   MALLOC_H
#include<malloc.h>
#endif
#ifndef   CTYPE_H
#include<ctype.h>
#endif
#ifndef   MATH_H
#include<math.h>
#endif

// 用字符串形式比较两个超大数(兼容整数和小数)的大小
// s1>s2返回1 s1<s2返回-1 s1=s2返回0
int s1_compare_s2(char *s1, char *s2)
{
	if (s1 == NULL || s2 == NULL)
		return -2;
	// 首先获取s1和s2的长度
	unsigned int s1len = strlen(s1), s2len = strlen(s2);
	// s1和s2对齐后的长度相等
	unsigned int len = 0;
	// 统计小数点的个数
	unsigned int num = 0;
	// s1 和 s2 的小数标记 是小数赋值1 否则0
	int sign1 = 0, sign2 = 0;
	// 小数点位置索引
	unsigned int index1 = 0, index2 = 0;
	// 非法字符退出
	for (int i = 0; i < s1len; i++)
	{
		if (*(s1 + i) == '.')
		{
			num++;
			sign1 = 1;
			index1 = i;
		}
		if ((!isdigit(*(s1 + i)) && *(s1 + i) != '.') || num > 1)
			return -2;
	}
	// 重置num值
	num = 0;
	// 非法字符退出
	for (int i = 0; i < s2len; i++)
	{
		if (*(s2 + i) == '.')
		{
			num++;
			sign2 = 1;
			index2 = i;
		}
		if ((!isdigit(*(s2 + i)) && *(s2 + i) != '.') || num > 1)
			return -2;
	}
	// ------------------------------
	int len1 = 0;
	// s1整数部分长度
	// 计算len1的长度
	if (sign1 == 0)
	{
		len1 = s1len;
		// 是整数
	}
	else if (sign1 == 1)
	{
		len1 = index1;
		// 是小数
	}
	int len2 = 0;
	// s2整数部分长度
	// 计算len2的长度
	if (sign2 == 0)
	{
		len2 = s2len;
		// 是整数
	}
	else if (sign2 == 1)
	{
		len2 = index2;
		// 是小数
	}
	// 计算对齐总长度len
	len =
		(len1 > len2 ? len1 : len2) + ((s1len - len1) >
									   (s2len - len2) ? (s1len - len1) : (s2len - len2));
	// 动态分配内存 存放对齐后的s1 和s2
	char *ps1 = (char *)malloc(sizeof(char) * len);
	char *ps2 = (char *)malloc(sizeof(char) * len);
	// 初始化指针所指的内存区域
	memset(ps1, '0', len);
	memset(ps2, '0', len);
	// s1和s2复制到内存指针中
	for (int i = 0; i < s1len; i++)
	{
		// 遇到小数点 把其替换成'0' 反正不影响判断结果
		// 这个特殊'0'的位置索引前面已经被标记过了
		if (*(s1 + i) == '.')
		{
			*(ps1 + i) = '0';
		}
		else
		{
			*(ps1 + i) = *(s1 + i);
		}
	}
	for (int i = 0; i < s2len; i++)
	{
		// 遇到小数点 把其替换成'0' 反正不影响判断结果
		// 这个特殊'0'的位置索引前面已经被标记过了
		if (*(s2 + i) == '.')
		{
			*(ps2 + i) = '0';
		}
		else
		{
			*(ps2 + i) = *(s2 + i);
		}
	}
	// 向右平移对齐 平移单位n
	int n = 0;
	n = abs(len1 - len2);
	char *ps1_1 = ps1 + n;
	char *ps2_1 = ps2 + n;
	if (len1 > len2)
	{
		// s2整体右移动n位 源ps2 目标ps2_1
		memmove(ps2_1, ps2, s2len);
		// 腾出位置用'0'填充
		for (int i = 0; i < n; i++)
		{
			*(ps2 + i) = '0';
		}
	}
	else if (len1 < len2)
	{
		// s1整体右移动n位 源ps1 目标ps1_1
		memmove(ps1_1, ps1, s1len);
		// 腾出位置用'0'填充
		for (int i = 0; i < n; i++)
		{
			*(ps1 + i) = '0';
		}
	}
	// 开始比较从低索引开始
	for (int i = 0; i < len; i++)
	{
		if (*(ps1 + i) > *(ps2 + i))
			return 1;
		// s1大于s2返回1
		if (*(ps1 + i) < *(ps2 + i))
			return -1;
		// s1小于s2返回-1
	}
	free(ps1);
	free(ps2);
	return 0;
}

char *daoshu(char *fenmu, unsigned int maxlen)
{
	// 分母(除数)有效字串
	char *fenmu0 = delInvalidZeros(fenmu);
	if (!fenmu0)
		return 0;
	// 分母长度fmlen
	unsigned int fmlen = strlen(fenmu0);
	// 存放分母的0到9倍数据
	char *fmtimes[10];
	// 商放置区,最大长度maxlen
	char *shang = NULL;
	shang = (char *)calloc(sizeof(char), (maxlen + 1));
	if (!shang)
		return 0;
	memset(shang, '\0', maxlen + 1);
	// 分子(被除数)缓冲区,长度分母长度+1'\0'
	char *fenzi_buf = (char *)calloc(sizeof(char), fmlen + 2);
	if (!fenzi_buf)
		return 0;
	memset(fenzi_buf, '\0', fmlen + 2);
	fenzi_buf[0] = '1';
	// 求分母0-9倍的值
	fmtimes[0] = "0";
	for (int i = 1; i < 10; i++)
	{
		char stmp[2];
		stmp[0] = i + '0';
		stmp[1] = '\0';
		fmtimes[i] = delInvalidZeros(wgx_mcl(fenmu0, stmp));
	}
	// 比较分子分母大小信号
	int sign;
	int s_i = 0;
	// 商递增
	int fz_i = 0;
	// 分子递增 "1\0"
	int fz_len = 2;
	// 分子长度
	int sign1 = 0;
	// 信号
	unsigned int n = maxlen;
	// 总循环次数
	while (fz_i < maxlen && n--)
	{
		sign = s1_compare_s2(fenzi_buf, fenmu0);
		if (sign == 0)
		{
			strncat(shang, "1", 2);
			memmove(shang + 2, shang + 1, strlen(shang) - 1);
			*(shang + 1) = '.';
			return shang;
		}
		else if (sign == -1)
		{
			strncat(shang, "0", 2);
			strncat(fenzi_buf, "0", 2);
		}
		else if (sign == 1)
		{
			break;
		}
	}
	char tmp[2];
	while (n--)
	{
		sign1 = s1_compare_s2(fenzi_buf, fenmu0);
		int i;
		if (sign1 == 1)
		{
			for (i = 9; i > 0; i--)
			{
				sign = s1_compare_s2(fmtimes[i], fenzi_buf);
				if (sign == 0 || sign == -1)
				{
					tmp[0] = i + '0';
					tmp[1] = '\0';
					strncat(shang, tmp, 2);
					if (sign == 0)
					{
						memmove(shang + 2, shang + 1, strlen(shang) - 1);
						*(shang + 1) = '.';
						return shang;
					}
					strcpy(fenzi_buf, delInvalidZeros(wgx_sub(fenzi_buf, fmtimes[i])));
					strncat(fenzi_buf, "0", 2);
					break;
				}
			}
		}
		else if (sign1 == 0)
		{
			strncat(shang, "1", 2);
			memmove(shang + 2, shang + 1, strlen(shang) - 1);
			*(shang + 1) = '.';
			return shang;
		}
		else if (sign1 == -1)
		{
			strncat(shang, "0", 2);
			strncat(fenzi_buf, "0", 2);
		}
	}
	// 01
	memmove(shang + 2, shang + 1, strlen(shang) - 1);
	*(shang + 1) = '.';
	free(fenmu0);
	free(fenzi_buf);
	return shang;
}

// 去掉无效0,用完记得释放指针
char *delInvalidZeros(char *str)
{
	int len = strlen(str);
	// if(len==1)return str;
	int flag = 0;
	// 小数标记符号
	char c = '.';
	char *valStr = (char *)calloc(sizeof(char), (len + 1));
	if (!valStr)
		return NULL;
	if (strchr(str, c) != NULL)
	{
		flag = 1;
	}
	int i_index = 0;
	// 整数时第一个非零索引
	int j_index = 0;
	// 小数首索引
	int k_index = 0;
	// 小数尾索引
	if (flag == 0)
	{
		for (int i = 0; *(str + i) != '\0'; i++)
		{
			if (*(str + i) != '0')
			{
				i_index = i;
				break;
			}
		}
	}
	else if (flag == 1)
	{
		// 尾索引
		for (int i = len - 1; i >= 0; i--)
		{
			if (*(str + i) == '.')
			{
				k_index = i - 1;
				break;
			}
			else if (*(str + i) != '0')
			{
				k_index = i;
				break;
			}
		}
		// 首索引
		for (int i = 0; i < len; i++)
		{
			if (*(str + i + 1) == '.')
			{
				j_index = i;
				break;
			}
			else if (*(str + i) != '0')
			{
				j_index = i;
				break;
			}
		}
	}
	// 把有效字串复制到valStr
	if (flag == 1)
		memcpy(valStr, (str + j_index), 1 + k_index - j_index);
	else if (flag == 0)
		memcpy(valStr, str + i_index, len - i_index);
	return valStr;
}

// 加法算法
char *wgx_add(char *s1, char *s2)
{
	int s1len = strlen(s1);
	int s2len = strlen(s2);
	int len1 = 0, len2 = 0;
	// 对拷s1和s2并转换成数字后补齐位数后的长度,若是小数其实len1和len2的长度是一样的
	int count1 = 0, count11 = 0;
	// 分别是第一个数的小数部分长度 和 整数部分长度
	int F1 = 0;
	// 用于判断是否是小数,是小数F1=1,否则F1=0
	for (int i = 0; i < s1len; i++)
	{
		if (*(s1 + i) == '.')
		{
			F1 = 1;
			break;
		}
	}
	// 若是小数则 计算小数部分长度
	for (int i = s1len - 1; i >= 0 && (F1 == 1); i--)
	{
		if (*(s1 + i) != '.')
			count1++;
		else
			break;
	}
	// 计算第一个加数的整数部分长度
	count11 = (F1 == 1) ? (s1len - 1 - count1) : s1len;
	// 相同方法处理第二个加数
	int count2 = 0, count22 = 0;
	int F2 = 0;
	for (int i = 0; i < s2len; i++)
	{
		if (*(s2 + i) == '.')
		{
			F2 = 1;
			break;
		}
	}
	for (int i = s2len - 1; i >= 0 && (F2 == 1); i--)
	{
		if (*(s2 + i) != '.')
			count2++;
		else
			break;
	}
	count22 = (F2 == 1) ? (s2len - 1 - count2) : s2len;
	len1 = (count1 > count2) ? count1 : count2;
	int cc = len1;
	// 用于后面标记小数的位置,这几行语句顺序不能颠倒
	len1 += (count11 > count22) ? count11 : count22;
	len2 = len1;
	// 为两个加数定义为a和b并为其动态分配内存空间
	int *a = (int *)malloc(sizeof(int) * len1);
	int *b = (int *)malloc(sizeof(int) * len2);
	if (!a || !b)
		return "error";
	// 初始化a和b len1和len2其实是一样大的
	for (int i = 0; i < len1; i++)
	{
		*(a + i) = 0;
		*(b + i) = 0;
	}
	// 定义和变量 以及取得长度
	int len = len1 + 1;
	int *sum = (int *)malloc(sizeof(int) * len);
	if (!sum)
		return "error";
	// 初始化和变量
	for (int i = 0; i < len; i++)
		*(sum + i) = 0;
	int tt1 = count1 - count2;
	// 用计算补齐几个0用
	for (int i = s1len - 1, j = len1 - 1; j >= 0; i--, j--)
	{
		if (tt1 < 0)
		{
			while (tt1)
			{
				*(a + j--) = 0;
				tt1++;
			}
		}
		if (*(s1 + i) == '.')
			i--;
		if (i >= 0)
			*(a + j) = *(s1 + i) - '0';
		else
			*(a + j) = 0;
	}
	int tt2 = count2 - count1;
	// 用计算补齐几个0用
	for (int i = s2len - 1, j = len2 - 1; j >= 0; i--, j--)
	{
		if (tt2 < 0)
		{
			while (tt2)
			{
				*(b + j--) = 0;
				tt2++;
			}
		}
		if (*(s2 + i) == '.')
			i--;
		if (i >= 0)
			*(b + j) = *(s2 + i) - '0';
		else
			*(b + j) = 0;
	}
	int cou = 0;
	for (int i = len - 1, j = len1 - 1, k = len2 - 1; i >= 0; i--, j--, k--)
	{
		cou++;
		if (cou <= len1)
		{
			*(sum + i) = *(a + j) + *(b + k);
		}
		else
			*(sum + i) = 0;
	}
	int temp1 = 0;
	for (int i = len - 1; i >= 0; i--)
	{
		temp1 = *(sum + i);
		*(sum + i) = *(sum + i) % 10;
		if (i > 0)
			*(sum + i - 1) += temp1 / 10;
	}
	// 输出
	char *sumres = (char *)malloc(sizeof(char) * (len + 1));
	if (!sumres)
		return "error!";
	memset(sumres, '0', len + 1);
	int i, j;
	for (i = 0, j = 0; i < len; i++, j++)
	{
		if ((F1 || F2) && (i == (len - cc)))
		{
			*(sumres + i) = '.';
			j = i + 1;
		}
		*(sumres + j) = (char)(*(sum + i) + '0');
	}
	*(sumres + j) = '\0';
	// 释放
	free(a);
	free(b);
	free(sum);
	return sumres;
}

// 减法算法
char *wgx_sub(char *s1, char *s2)
{
	int abc = 1;
	// 用于判断结果正负 负数abc赋值为-1
	int s1len = strlen(s1);
	int s2len = strlen(s2);
	int len1 = 0, len2 = 0;
	// 对拷s1和s2并转换成数字后补齐位数后的长度,若是小数其实len1和len2的长度是一样的
	int count1 = 0, count11 = 0;
	// 分别是第一个数的小数部分长度 和 整数部分长度
	int F1 = 0;
	// 用于判断是否是小数,是小数F1=1,否则F1=0
	for (int i = 0; i < s1len; i++)
	{
		if (*(s1 + i) == '.')
		{
			F1 = 1;
			break;
		}
	}
	// 若是小数则 计算小数部分长度
	for (int i = s1len - 1; i >= 0 && (F1 == 1); i--)
	{
		if (*(s1 + i) != '.')
			count1++;
		else
			break;
	}
	// 计算第一个加数的整数部分长度
	count11 = (F1 == 1) ? (s1len - 1 - count1) : s1len;
	// 相同方法处理第二个加数
	int count2 = 0, count22 = 0;
	int F2 = 0;
	for (int i = 0; i < s2len; i++)
	{
		if (*(s2 + i) == '.')
		{
			F2 = 1;
			break;
		}
	}
	for (int i = s2len - 1; i >= 0 && (F2 == 1); i--)
	{
		if (*(s2 + i) != '.')
			count2++;
		else
			break;
	}
	count22 = (F2 == 1) ? (s2len - 1 - count2) : s2len;
	len1 = (count1 > count2) ? count1 : count2;
	int cc = len1;
	// 用于后面标记小数的位置,这几行语句顺序不能颠倒
	len1 += (count11 > count22) ? count11 : count22;
	len2 = len1;
	// 为两个加数定义为a和b并为其动态分配内存空间
	int *a = (int *)malloc(sizeof(int) * len1);
	int *b = (int *)malloc(sizeof(int) * len2);
	if (!a || !b)
		return "error";
	// 初始化a和b len1和len2其实是一样大的
	for (int i = 0; i < len1; i++)
	{
		*(a + i) = 0;
		*(b + i) = 0;
	}
	// 定义结果变量c 以及取得长度
	int len = len1;
	int *c = (int *)malloc(sizeof(int) * len);
	if (!c)
		return "error";
	// 初始化和变量
	for (int i = 0; i < len; i++)
		*(c + i) = 0;
	int tt1 = count1 - count2;
	// 用计算补齐几个0用
	for (int i = s1len - 1, j = len1 - 1; j >= 0; i--, j--)
	{
		if (tt1 < 0)
		{
			while (tt1)
			{
				*(a + j--) = 0;
				tt1++;
			}
		}
		if (*(s1 + i) == '.')
			i--;
		if (i >= 0)
			*(a + j) = *(s1 + i) - '0';
		else
			*(a + j) = 0;
	}
	int tt2 = count2 - count1;
	// 用计算补齐几个0用
	for (int i = s2len - 1, j = len2 - 1; j >= 0; i--, j--)
	{
		if (tt2 < 0)
		{
			while (tt2)
			{
				*(b + j--) = 0;
				tt2++;
			}
		}
		if (*(s2 + i) == '.')
			i--;
		if (i >= 0)
			*(b + j) = *(s2 + i) - '0';
		else
			*(b + j) = 0;
	}
	// -------------------
	// 判断a与b的大小,大数作为第一个数
	int a1 = 0, b1 = 0;
	// 用于判断a和b哪个大大的就赋值为1
	for (int i = 0; i < len1; i++)
	{
		int tmp = *(a + i) - *(b + i);
		if (tmp > 0)
		{
			a1 = 1;
			break;
		}
		else if (tmp < 0)
		{
			b1 = 1;
			abc = -1;
			break;
		}
		// 如果循环结束a1==0 && b1==0表示a和b相等
		// 结果直接为0即可
	}
	// a>=b时情况
	int cou = 0;
	if ((a1 == 1) || (a1 == 0 && b1 == 0))
		for (int i = len - 1, j = len1 - 1, k = len2 - 1; i >= 0; i--, j--, k--)
		{
			int vv = 0;
			// 是否借位的记号 借位赋值1
			int n = 0;
			// 借位移动了几位
			cou++;
			int tmp1 = *(a + j) - *(b + k);
			if (cou <= len1)
			{
				if (tmp1 >= 0)
				{
					*(c + i) = tmp1;
				}
				else
					// 向高位(低索引处借位)
				{
					tmp1 += 10;
					*(c + i) = tmp1;
					vv = 1;
				}
			}
			else
				*(c + i) = 0;
			// 处理借位
			if (vv == 1)
				for (int ccc = j - 1; ccc >= 0 && j > 0; ccc--)
				{
					if (*(a + ccc) == 0)
						n++;
					else
						break;
				}
			if (vv == 1)
				for (int bb = n; bb < j && bb > 0; bb--)
				{
					*(a + j - bb) += 9;
				}
			// 借位处减去1
			if (vv == 1 && j >= (n + 1))
				*(a + (j - n - 1)) -= 1;
			// 重置
			vv = 0;
			n = 0;
		}
	// a<b情况
	int cou2 = 0;
	if ((b1 == 1))
		for (int i = len - 1, j = len1 - 1, k = len2 - 1; i >= 0; i--, j--, k--)
		{
			int vv = 0;
			// 是否借位的记号 借位赋值1
			int n = 0;
			// 借位移动了几位
			cou2++;
			int tmp1 = *(b + k) - *(a + j);
			if (cou2 <= len2)
			{
				if (tmp1 >= 0)
				{
					*(c + i) = tmp1;
				}
				else
					// 向高位(低索引处借位)
				{
					tmp1 += 10;
					*(c + i) = tmp1;
					vv = 1;
				}
			}
			else
				*(c + i) = 0;
			// 处理借位
			if (vv == 1)
				for (int ccc = j - 1; ccc >= 0 && j > 0; ccc--)
				{
					if (*(b + ccc) == 0)
						n++;
					else
						break;
				}
			if (vv == 1)
				for (int bb = n; bb < k && bb > 0; bb--)
				{
					*(b + k - bb) += 9;
				}
			// 借位处减去1
			if (vv == 1 && k >= (n + 1))
				*(b + (k - n - 1)) -= 1;
			// 重置
			vv = 0;
			n = 0;
		}
	char *resc = (char *)malloc(sizeof(char) * (len + 1));
	if (!resc)
		return "error!";
	memset(resc, '0', len + 1);
	// 输出
	int i, j;
	for (i = 0, j = 0; i < len; i++, j++)
	{
		if (abc == -1)
		{
			*(resc + j++) = '-';
			abc = 1;
		}
		if ((F1 || F2) && (i == (len - cc)))
		{
			*(resc + j++) = '.';
		}
		*(resc + j) = (char)(*(c + i) + '0');
	}
	*(resc + j) = '\0';
	// 释放
	free(a);
	free(b);
	free(c);
	return resc;
}

// 大数乘法算法
char *wgx_mcl(char *s1, char *s2)
{
	int F1 = 0, F2 = 0;
	// 分别用于判断s1,s2是否小数,是小数对应赋值1
	int n1 = 0, n2 = 0;
	// 分别是源s1,s2小数位数
	char *P1 = NULL, *P2 = NULL;
	// 分别是源s1,s2的小数点位置索引,整数则为NULL
	int len1 = strlen(s1), len2 = strlen(s2);
	// 分别是源s1,s2的长度
	int *product1 = (int *)malloc(sizeof(int) * (len1 + len2 + 1));
	// 乘积存储区1
	char *product2 = (char *)malloc(sizeof(char) * (len1 + len2 + 2));
	// 乘积存储区2
	memset(product1, 0, len1 + len2 + 1);
	memset(product2, '0', len1 + len2 + 2);
	for (int i = 0; i <= len1 + len2; i++)
	{
		*(product1 + i) = 0;
	}
	P1 = strchr(s1, '.');
	P2 = strchr(s2, '.');
	if (P1)
	{
		F1 = 1;
		n1 = len1 - (int)(P1 - s1) - 1;
	}
	if (P2)
	{
		F2 = 1;
		n2 = len2 - (int)(P2 - s2) - 1;
	}
	// 先忽略小数点 k控制递增梯度,z控制行
	int tmp = 0;
	for (int i = len2 - 1, z = len2 + len1; i >= 0; i--, z--)
	{
		// 第二个乘数遇到小数点跳过当前轮循环
		if (*(s2 + i) == '.')
		{
			z++;
			continue;
		}
		for (int j = len1 - 1, k = z; j >= 0; j--, k--)
		{
			// 第一个乘数遇到小数点跳过当前轮循环
			if (*(s1 + j) == '.')
				j--;
			tmp = (int)(*(s1 + j) - '0') * (int)(*(s2 + i) - '0');
			*(product1 + k) += tmp % 10;
			// 当前位
			*(product1 + k - 1) += tmp / 10;
			// 进位
		}
		tmp = 0;
	}
	// 进位
	for (int i = len1 + len2; i > 0; i--)
	{
		tmp = *(product1 + i);
		*(product1 + i) = tmp % 10;
		*(product1 + i - 1) += tmp / 10;
	}
	// product2的最高索引处放置放置'\0'
	for (int i = len1 + len2, j = len1 + len2; i >= 0 && j >= 0; i--, j--)
	{
		if ((F1 || F2) && i == (len1 + len2 - n1 - n2))
		{
			*(product2 + j--) = '.';
			// printf("%d",*(product2+j));
			F1 = 0;
			F2 = 0;
		}
		*(product2 + j) = (char)(*(product1 + i) + '0');
		// printf("%d",*(product2+j));
	}
	*(product2 + len1 + len2 + 1) = '\0';
	free(product1);
	return product2;
}

// 大数除法算法 maxlen是计算最大精度(长度)
char *wgx_div(char *s1, char *s2, unsigned int maxlen)
{
	char *s = (char *)malloc(2);
	memcpy(s, "1", 2);
	if (s1_compare_s2(s2, "0") == 0)
		return 0;
	if (s1_compare_s2(s1, s2) == 0)
		return s;
	if (s1_compare_s2(s1, "0") == 0 && s1_compare_s2(s2, "0") != 0)
	{
		memmove(s, "0", 2);
		return s;
	}


	int len2 = strlen(s2);
	int len2_end;

	char *pp2 = (char *)malloc(len2 + 1);
	if (!pp2)
		return 0;
	memcpy(pp2, s2, len2 + 1);

	char *p2_poi = strchr(pp2, '.');



	if (p2_poi == NULL)
		return (delInvalidZeros(wgx_mcl(s1, daoshu(s2, maxlen))));
	else
	{
	    len2_end = len2 - (p2_poi - pp2) - 1;
		char exarr[len2_end + 2];
		memmove(p2_poi, p2_poi + 1, len2_end + 1);

		exarr[0] = '1';
		memset(exarr + 1, '0', len2_end);
		exarr[len2_end + 1] = '\0';

		return
			delInvalidZeros(wgx_mcl(exarr, (delInvalidZeros(wgx_mcl(s1, daoshu(pp2, maxlen))))));

	}
	return 0;
}
#endif
#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

滴水不穿石

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值