c++ 模拟浮点数运算

本文介绍了使用C++模拟浮点数运算,通过自定义数据类型来处理大数,并行计算高精度PI值。通过将数字转换为科学计数法,简化乘除运算。详细描述了加减、乘除、移位操作的实现,并针对除法采用了试除法。文章还提到了代码实现中的坑点,如输出浮点数的规格化处理,并预告了关于MPI并行化的进一步讨论。
摘要由CSDN通过智能技术生成

问题来源与多核程序设计的作业,尽可能并行计算高精度的pi值,就想拿个数组模拟一下,因为担心double的精度不够

计算pi的方法如下:


然后就是计算的过程,小数这东西真的不好处理,从方向上来说可以双向延伸,和xq讨论了下,突然想到把指数带进来,就是科学计数法的表示,但是不要求那么严格,限定有效数字(后面称为系数)的范围,我想把系数变成整数,就不用考虑小数点的事了

然后运算全部是整数参与运算,就是大数而已,这种模拟已经写过,把问题转变了熟悉的模型,然后开始入坑了.....


自定义新数据类型如下:

typedef struct sint{

	int digit[MAX]; //digit 0代表最低位,万进制加速运算
	int len; //代表系数长度
	int index;//代表指数(10进制)
	sint(){len=0;memset(digit,0,sizeof(digit));index=0;}
}sint;

万进制,每个int储存4位数字(首位除外)

举例 : 1.630523 表示成 digit[0]=0523=523 digit[1]=163,len=1,index=-6

这种模拟运算最麻烦的是乘除,有了指数之后,乘除方便多了,虽然加减要对齐了

加减

a*10^b+c*10^d, 首先要对阶,我把指数大的转化成指数小的,这样也是保证系数是整数,大的变小,指数减小,系数左移就行了

所以移位操作也是要支持的,整个数组都要移动,代价太大了...

a*10^b*c*10^d=a*c*10^(b+d) 用大数来乘就好了

浮点数最麻烦的就是除了

a*10^b/(c*10^d)

除发采用试除,需要不断保证系数a>b,小了就减少指数,我采用的一直往下除,直到小数点后100位,虽然可以支持上限到400,当然可以根据需要,定义digit数组的长度来改变

模拟人的计算,先找到最大的c,c*b<a,然后a-c*b=d,ans+=d 不断重复这个过程,直到a-c*b=0 或者到了小数点后100位

然后是c的确定,采用的是a的首位除以(b的首位+1),举个例子,62/27,直接拿6/3=2,c就是2,你会举出这样的反例,90/10,这样得到的不准确

没关系,因为不是算一次,如果判断首位相等,c就是1了,因为a系数始终大于b,然后继续迭代,小于的话就左移,指数减小就行了

然后是移位

比较坑的是输出浮点数

输出之前首先规格化,保证系数末尾不能有0,有就调整到指数上,这样就是右移了,但是这样可以解决不少麻烦

因为拿int储存的数据,万进制,有时候1代表的就是1,有时又代表的是0001

输出时先规格化,然后计算系数长度,是位数,和len不同,然后比较指数确定小数点的位置,然后逐位输出


这个东西虽然思路看上去不难,但是确实折腾人,写完感觉也是挺有收获,代码能力仍需加强

然后是全部代码,有空再详细一点描述mpi并行化与其它的一些细节

#include<iostream>
#include<cstdio>
#include<memory.h>
#include<sstream>
#include<math.h>
#include<cstdlib>
#define MAX 100
#define mod 10000
using namespace std;
typedef struct sint{

	int digit[MAX]; //digit 0代表最低位
	int len; //代表系数长度
	int inde
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值