【字符串】大数的乘法(包括浮点数)

一.大数乘法

我们知道,要运算两个数的乘法,c、c++语言里有专门的运算符*。但是当两个数超过一定的范围时,用普通的运算符会产生溢出,并不能得到正确的结果。如何进行运算呢?

      首先,要想保存一个大数,用正常的整形或浮点类型是不够的。所以我们可以采用字符串的形式对大数进行保存,然后编写算法,模拟乘法运算过程即可。

1.第一个问题:两个数字运算结果至多用多少位的字符串保存呢?

两个4位数相乘,最大值为9999*9999它的位数小于10000*10000的位数9位,所以两个数字相乘的结果至多不超过两数位数的和

2.第二个问题:运算的过程怎么模拟?

       
比如:我们可以先进行类乘和累加,把结果保存到相应的字符里,然后进行进位

1  2  3  4

            1  2  3

--------------------

        3  6   9  12             //一次类乘

   2  4   6   8

1 2  3  4

--------------------------

1 4 10 16 17 12             //累加  

1 5   1   7   8    2            //进位

但是,这里会出现的问题就是,如果当两个数的位数特别大是,先进行类乘累加,由于无符号字符能保存的最大值也只有255,后进行进位处理时,有可能字符保存的值已经溢出。所以,在进行处理时要一次类乘后进行进位,然后累加。

处理完思路后,编写代码会变得很轻松。

void bignum(char *num1, char *num2)
{
	int length1 = strlen(num1);
	int length2 = strlen(num2);
	int i, l;
	char *res = (char *)malloc(sizeof(char)*(length1 + length2)); //开辟相应内存
	memset(res, 0, sizeof(char)*(length1 + length2));
	for (i = length1 - 1; i >= 0; i--)
	for (l = length2 - 1; l >= 0; l--)
	{
		res[i + l + 1] += (num1[i] - '0')*(num2[l] - '0'); 类乘完累加
		res[i + l] += res[i + l + 1] / 10;    //马上进行进位
		res[i + l + 1] %= 10;
	}
	int count = 0;
	while (res[count] == 0)  //由于保存的结果是从右向左的,所以要消除左部分的0;
	{
		count++;
	}
	char* ret = (char *)malloc(sizeof(char)*(length1 + length2 + 2));
	memset(ret, 0, sizeof(char)*(length1 + length2 + 2));
	for (l = 0, i = count; i < length1 + length2; l++, i++)  //非0部分赋给ret
	{
		ret[l] = res[i] + '0';
	}
	printf("Ret=%s\n", ret);
	free(res);
	free(ret);
}
结果如图:

二:实现浮点数。

实现浮点数相乘,其实和整数差不多。只不过先得把浮点数转化为整数,并记录两个数小数点的位数和,然后再得到的整数上加上相应的小数点即可

void bignum_float(char *str1, char *str2)
{
	int length1 = strlen(str1);
	int length2 = strlen(str2);
	int flnum = -1;   //大数1的小数点位数
	int flnum2 =-1;   //数2的小数点位数
	char num1[500] = { 0 };
	char num2[500] = { 0 };
	int i, l;
	for (i=0,l=0; l < length1;i++,l++)
	{
		if (str1[l] == '.') //遇到小数点后 开始加一
		{
			flnum++;
			i--;
			continue;
		}
		if (flnum!=-1) flnum++; //统计小数点后的位数,由于会多加一次,所以初始值为-1
		num1[i] = str1[l];  //保存到新的数组里
	}

	for (i = 0,l = 0; l < length2; i++, l++)
	{
		if (str2[l] == '.')
		{
			flnum2++;
			i--;
			continue;
		}
		if (flnum2!=-1) flnum2++;
		num2[i] = str2[l];
	}
	if (flnum!=-1) length1 -= 1;   //如果数字存在小数点,则转化为整数后对应的长度-1
	if (flnum2!=-1) length2 -= 1;
	flnum = flnum + flnum2;
	char *res = (char *)malloc(sizeof(char)*(length1 + length2));
	memset(res, 0, sizeof(char)*(length1 + length2));
	for (i = length1-1; i>=0;i--)
	for (l=length2-1; l >= 0; l--)
		{
			res[i+l+1]+=(num1[i] - '0')*(num2[l] - '0');
			res[i + l] += res[i + l + 1] / 10;
			res[i + l + 1] %= 10;
		}
	int count = 0;
	while (res[count] == 0)
	{
		count++;
	}
	char* ret =(char *)malloc(sizeof(char)*(length1 + length2+2));
	memset(ret, 0, sizeof(char)*(length1 + length2 + 2));
	for (int n=0,l = 0,i=count; i < length1 + length2; l++, i++,n++)
	{
		if (n == length1 + length2 -count-flnum)   //在结果对应的位置加上小数点
		{
			ret[l] = '.';
			i--;
			continue;
		}
		ret[l] = res[i] + '0';
	}

	printf("Ret=%s\n",ret);
	free(res);
	free(ret);
}

结果:

时间: 2024-10-14 11:08:23

【字符串】大数的乘法(包括浮点数)的相关文章

LeetCode-Multiply Strings实现大数的乘法

Given two numbers represented as strings, return multiplication of the numbers as a string. Note: The numbers can be arbitrarily large and are non-negative. 题目当中主要是需要两个大数的乘法,一般大数都是用字符串进行保存 代码比较简单,主要是利用了一个vector反向的存储了计算的结果,然后reverse到string当中进行输出 这里当然可

字符串大数加减运算问题

这里自己利用STL模板中的容器和链表实现字符串大数加减运算. 1 #include<iostream> 2 #include<vector> 3 #include<list> 4 using namespace std; 5 6 list<char> Input_Number(list<char> ilist)//输入链表字符串,以‘#’作为结束符 7 { 8 cout<<"please Input string ,end

利用map和reduce编写一个str2float函数,把字符串&#39;123.456&#39;转换成浮点数123.456:

from functools import reduce CHAR_TO_FLOAT = { '0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, '.': -1 } def str2float(s): nums=map(lambda x:CHAR_TO_FLOAT[x],s) #print(list(nums)) point = 0 def str_division(f,n): nonlo

大数加法乘法

大数加法乘法: 1 /* 2 2015.4 3 大数加法,乘法 4 5 */ 6 #include <iostream> 7 #include <string> 8 #include <vector> 9 10 using namespace std; 11 #define MAX 99 12 #define MAXM 200 13 14 void BigNumAdd() 15 { 16 char strA[MAX], strB[MAX]; 17 cout <&l

vector、string实现大数加法乘法

理解 vector 是一个容器,是一个数据集,里边装了很多个元素.与数组最大的不同是 vector 可以动态增长. 用 vector 实现大数运算的关键是,以 string 的方式读入一个大数,然后将字串的每一个字符 s[i] 以 int 形式赋给 vector<int> a 中的每一个元素.然后将 a[i] 和 a[j] 加起来(或者乘起来).每两个元素加起来的结果 <= 18,乘起来的结果 <= 81. 用 string 实现大数加法的方法跟 vector 差不多,但是用 st

统计字符串以及打印乘法口诀表

1.统计字符串中有多少个数字.字母.空格以及其他字符 #!/usr/bin/env python # -*- coding:utf-8 -*- # @Time : 2018/1/24 21:29 # @Author : zhouyuyao # @File : countnums.py # PyCharm 2017.3.2 (Community Edition) # Build #PC-173.4127.16, built on December 19, 2017 # JRE: 1.8.0_152

shell实现trim函数-去除字符串两侧的空格(包括tab,space键)

shell实现trim函数效果去除字符串两侧的空格,以下三个命令等价,都能实现 sed 's/^\s*//' totrim.txt |sed 's/\s*$//'>trimed.txtsed 's/^\s*//;s/\s*$//' totrim.txt>trimed.txtsed -e 's/^\s*//' -e 's/\s*$//' totrim.txt>trimed.txt 主要就是利用正则表达式,^\s*表示字符串前面的零个或多个空格,\s*$表示字符串后面的零个或多个空格.

大数的乘法

题目描述 大数是指计算的数值非常大或者对运算的精度要求非常高,用已知的数据类型无法精确表示的数值.例如:我们要计算如下两个数的乘积时,用我们已知的数据类型是无法精确表示其结果的: a1 = 11111111111111111111111111111111111 b1 = 11111111111111111111111111111111111111 求:a1 * b1; 输入要求 输入两行:每行一个数字,每行的数字不超过100位: 输出要求 输出一行:为这两个大数的乘积 假如输入 11111111

关于大数的乘法(2的128次方)

用JDK自带的方法: 1 import java.math.BigDecimal; 2 3 public class Test 4 { 5 public static void main(String[] args)throws Exception 6 { 7 BigDecimal two = new BigDecimal("2"); 8 BigDecimal two_128 = new BigDecimal(two.pow(128).toString()); 9 10 System.