• 大数乘除法


    大数乘除法

    大数乘法

    代码

    /*
    大整数乘法
    https://blog.csdn.net/u010983881/article/details/77503519
    拟乘法累加 - 改进
    思路来源段落链接:
    https://blog.csdn.net/u010983881/article/details/77503519#:~:text=%E7%AC%AC%E4%BA%8C%E7%A7%8D%E6%96%B9%E6%B3%95%E3%80%82-,2%E3%80%81%E6%A8%A1%E6%8B%9F%E4%B9%98%E6%B3%95%E7%B4%AF%E5%8A%A0%20-%20%E6%94%B9%E8%BF%9B,-%E7%AE%80%E5%8D%95%E6%9D%A5%E8%AF%B4%EF%BC%8C%E6%96%B9%E6%B3%95 
    
    */ 
    
    #include <iostream>
    #include <string>
    #include <cstring>
    #include <cstdlib>
    
    using namespace std;
    
    // 将 ASCII 字符转换成对应的数 
    #define Char2Int(x) ((x) - 0x30)
    // 将 数 转换成 ASCII 字符  
    #define Int2Char(x) ((x) + 0x30)
    
    char * big_num_mutiply(char * a, char * b);
    
    
    int main()
    {
    	cout << big_num_mutiply("12345678", "12345678") << endl;;//预期输出 152,415,765,279,684
    	cout << big_num_mutiply("1234", "5678") << endl;//预期输出 7006652
    	cout << big_num_mutiply("123456789101112131415", "123456789101112131415") << endl;
    	//预期输出   15241578775156479157107515989284229902225
    	cout << big_num_mutiply("15241578775156479157107515989284229902225", "15241578775156479157107515989284229902225") << endl;
    	// 预期输出  232305723559300479424424097917104370511691764893690487487812974988368833059950625
    	return 0; 
    }
    
    /*
    a 是被乘数
    b 是乘数
    返回 a*b 结果字符串 
    目前只支持正整数 
    思路来源链接:
    https://blog.csdn.net/u010983881/article/details/77503519#:~:text=%E7%AC%AC%E4%BA%8C%E7%A7%8D%E6%96%B9%E6%B3%95%E3%80%82-,2%E3%80%81%E6%A8%A1%E6%8B%9F%E4%B9%98%E6%B3%95%E7%B4%AF%E5%8A%A0%20-%20%E6%94%B9%E8%BF%9B,-%E7%AE%80%E5%8D%95%E6%9D%A5%E8%AF%B4%EF%BC%8C%E6%96%B9%E6%B3%95 
    */
    char * big_num_mutiply(char * a, char * b)
    {
    	//a_len 是被乘数的位数  b_len 是乘数的位数 
    	int a_len = strlen(a);
    	int b_len = strlen(b);
    	int res_len = a_len + b_len - 1;//乘积数字表示的位数是 乘数位数 + 被乘数位数 - 1 
    	int increment = 0; //进位 
    	int * res_int = new int[res_len];//乘积的数字表示 也是大端对齐 即 LSB 在 下标为 0 的位置 
    	char * res_str_low = new char[res_len + 1];//乘积的字符串表示 
    	//1)大端对齐 最高位放在 下标为 0 的位置 (进位除外) 
    	//2)长度: res_len + 1 ,res_str[res_len] = '' 
    	
    
    	memset(res_int, 0, res_len*sizeof(int));
    	// 乘数在外围,被乘数在内层 
    	for (int j = b_len - 1; j >= 0; j--)
    	{
    		for (int i = a_len - 1; i >= 0; i--)
    		{
    			int temp = 	Char2Int(a[i]) * Char2Int(b[j]);
    			int index = i + j;// 临时结果在乘积中的位置下标 
    			res_int[index] += temp;
    		}
    	}
    	
    	res_str_low[res_len] = '';
    	// 将 res_int 转换成 res_str_low, 同时处理进位 
    	for (int k = res_len - 1; k >= 0; k--)
    	{
    		res_int[k] += increment;
    		res_str_low[k] = Int2Char(res_int[k] % 10);
    		increment = res_int[k] / 10;
    	}
    	delete res_int;
    	
    	//若有进位,则将其转换成字符串 ,并将进位字符串和低位字符串拼接起来
    	if (increment)
    	{ 
    		char * res_str_high = new char[res_len];// 用于保存进位 
    		itoa(increment, res_str_high, 10);
    		strcat(res_str_high, res_str_low);
    		return res_str_high;
    	}
    	else
    	{
    		return res_str_low;
    	}
    
    }
    

    python 验证

    a = 123456789101112131415
    b = 123456789101112131415
    c = a * b
    print(c)
    # 预期输出 15241578775156479157107515989284229902225
    a = 15241578775156479157107515989284229902225
    c = a * a
    print(c)
    # 预期输出  232305723559300479424424097917104370511691764893690487487812974988368833059950625
    
    

    大数除法

    代码

    //大整数除法, 只考虑被除数很大的情况 
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <assert.h>
    //#include <limits.h>
    
    using namespace std;
    // 将 ASCII 字符转换成对应的数 
    #define Char2Int(x) ((x) - 0x30)
    // 将 数 转换成 ASCII 字符  
    #define Int2Char(x) ((x) + 0x30)
    // int 可以进行正常除法运算的最多位数 是 9
    // 见 limits.h 里面 #define INT_MAX 2147483647
    // 共 10位 , 最多可用的是 9 位 
    #define MAX_WIDTH 9
    
    char * big_num_division(char * dividend, char * divisor);
    
    int main()
    {
    	cout << big_num_division("123456789101112131415", "8") << endl; //预期输出 15432098637639016426
    	cout << big_num_division("12345", "678910") << endl; //预期输出 0 
    	cout << big_num_division("123456789101112131415", "3") << endl;// 预期输出 41152263033704043805
    	cout << big_num_division("1234567891011121314", "8") << endl; // 预期输出 154320986376390164
    	return 0;
    } 
    
    // dividend 是被除数  divisor 是除数
    char * big_num_division(char * dividend, char * divisor)
    {
    	int dividend_len = strlen(dividend);
    	int divisor_len = strlen(divisor);
    	assert(divisor_len < MAX_WIDTH);// 默认除数很小,不超过范围 
    	int divisor_int = atoi(divisor); 
    	char * res_str = new char[dividend_len];//结果字符串  
    	memset(res_str, 0, sizeof(char) * dividend_len);
    	
    	// 当被除数位数小于等于除数时,直接返回字符串 "0" 
    	if (dividend_len < divisor_len)
    	{
    		delete res_str;
    		return "0";
    	}
    	
    	// 当被除数位数在 MAX_WIDTH 以内时,使用 atoll 将其转换成 int 进行正常的除法运算 ,返回结果字符串
    	if (dividend_len <= MAX_WIDTH)
    	{
    		itoa(atoi(dividend)/atoi(divisor), res_str, 10);
    		return res_str;
    	}
    
    	// 当被除数位数多于 MAX_WIDTH 时,模拟手动竖式除法进行计算
    	int i = 0;
    	int j = 0;
    	int remainder = 0;
    	int quotient = 0;
    	while (quotient == 0)//去除开头的 0
    	{
    		quotient = (Char2Int(dividend[i]) + remainder * 10) / divisor_int;
    		remainder = (Char2Int(dividend[i]) + remainder * 10) % divisor_int;
    		i++;
    		if (quotient)
    			res_str[j++] = Int2Char(quotient);
    	}
    		
    	for (; i < dividend_len; i ++)
    	{
    		quotient = (Char2Int(dividend[i]) + remainder * 10) / divisor_int;
    		remainder = (Char2Int(dividend[i]) + remainder * 10) % divisor_int;
    		res_str[j++] = Int2Char(quotient);		
    	}
    	res_str[j] = '';
    	return res_str;
    }
    

    python 验证

    c = 16151413121110987654321 // 123456789101112131415
    print('16151413121110987654321 // 123456789101112131415 = %u' % c)
    # 预期输出 130
    
    c = 123456789101112131415//8
    print('123456789101112131415//8 = %u' % c)
    # 预期输出 15432098637639016426
    
    
    c = 123456789101112131415//3
    print('123456789101112131415//3 = %u' % c)
    # 预期输出 41152263033704043805
    
    c = 1234567891011121314//8
    print('1234567891011121314//8 = %u' % c)
    # 预期输出 154320986376390164
    
    
  • 相关阅读:
    Geoserver通过ajax跨域访问服务数据的方法(含用户名密码认证的配置方式)
    123
    递归____蛮好的例子 蓝桥
    博弈_____威佐夫博奕
    123123
    sort
    int ,long , long long类型的范围
    数学推导_循环小数转分数
    下一步:结构体 背包 库函数
    回溯____蓝桥 棋盘
  • 原文地址:https://www.cnblogs.com/studentWangqy/p/15526952.html
Copyright © 2020-2023  润新知