⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 myfloat.c

📁 纯C写的48位软件模拟浮点运算,可移植 测试版
💻 C
📖 第 1 页 / 共 4 页
字号:
	xdata S8		fet2;

	ft1 = a;
	ft2 = b;
	fet1 = ft1.e;
	fet2 = ft2.e;
	// 判断指数的正负
	if ( (ft1.e & BIT_MASKES) == BIT_MASKES )
	{
		fet1 = (S8)( 0x80 |( (U8) ( ~( (~ft1.e + 1 ) & 0x3f ) +1 ) ) ); 	// 得到原码,再求补码,由六位真值变七位真值
	}
	if ( (ft2.e & BIT_MASKES) == BIT_MASKES  )		
	{
		fet2 = (S8)( 0x80 |( (U8) ( ~( (~ft2.e + 1 ) & 0x3f ) +1 ) ) ); 	// 得到原码,再求补码,由六位真值变七位真值
	}

	if ( fet1 == fet2 )// 指数相同,尾数直接相加,指数补码加1可直接进行
	{
		fmt2ml = ft2.ml;
		fmt2mh = ft2.mh;

	}
	// 保证ft1中为指数较大的大数,ft2中为指数较小的数
	if ( fet1 < fet2 )
	{
		S8 t;

		ft1 = b;
		ft2 = a;
		t=fet1;
		fet1=fet2;
		fet2=t;
	}

	// 加数ft1的指数大于加数ft2的指数,处理较小的数ft2,使其右移成与大数指数一致,再尾数相加,指数相加
	fet = fet1 - fet2;
	if ( fet >=8 ) // 加数的指数大于被加数指数超过8,即要移的位多于8位,这时ft2尾数的高位mh即右移位后全为0
	{
		fmt2ml = ( ft2.ml >> fet );// ft2.ml 右移
		fmt2mh = ( (U32)ft2.mh )<< (32 -fet ); //ft2.mh 的8个位移到ft2.ml的左边
		fmt2ml = fmt2mh | fmt2ml; //拼装成右移好的新的ft2的尾数(全在32位中,因fet>=8)
		fmt2mh = 0; // 因为8位全右移走了.
	}
	if ( ( fet >0 ) && ( fet < 8 ) )  //即0<fet<8 时,这时ft2
	{
		fmt2ml = ( ft2.ml >> fet );// ft2.ml 右移

		//ft2.mh 先左移8-fet后就除去了高位不需要移入ml的高位的部分,
		//然后转成U32再左移24位,这样就移到U32位的最高位,即ml的最高位,
		fmt2mh =( (U32) ( (U8)(ft2.mh << (8 -fet ) ) ) )<< 24; 

		fmt2ml = fmt2mh | fmt2ml; //拼装成右移好的新的ft2的尾数
		
		// ft2.mh 右移fet,得到新右移后的mh的尾数,为共用一个变量采用了U32类型的fmt2mh变量
		fmt2mh = (U32) ( ft2.mh >> fet );
	}
	// 带进位的40位二进制相加
	fmtmladd = fmt2ml + ft1.ml ; // 低32位相加
	if ( fmtmladd < ft1.ml ) // 所得和小于其中任何一个加数,说明和大于最大值,即有进位
	{
		fmtmlC = 1; // ml相加的进位位为1
	}
	else
	{
		fmtmlC = 0; 
	}
	// 高8位相加
	fmtmhaddt =  ( (U8)fmt2mh  + fmtmlC );
	fmtmhC = 0;
	if ( fmtmhaddt < (U8)fmt2mh )//有进位 ,因为fmtmlC最大只能是1,所以只有fmt2mh=0xff时才可能这进位,而这时,fmtmhaddt =0;所以再加上ft1.mh时不可能有进位了
	{
		fmtmhC = 1;
		fmtmhadd = ft1.mh + fmtmhaddt;// 不可能有进位了,因为这时fmthaddt=0
		if ( 63==ft1.e   )// (ft1.e范围在(-64~63),那加上进位就溢出了,则直接取63
		{
			ft.e = 63;
		}
		else
		{
			ft.e = ft1.e + fmtmhC; // 和的指数=大数的指数+1
			// 然后尾数左移一位,其中mh的最高位为进位位fmtmhC
			fmtmladd = ( ( (U32)(fmtmhadd &0x01) ) << 31 )|( fmtmladd >> 1 );
			fmtmhadd = ( (U8)( fmtmhC << 7 ) )| (U8)( ( fmtmhadd >> 1 ));
		}
	}
	else
	{
		fmtmhadd = ft1.mh + fmtmhaddt;// 
		if ( fmtmhadd < ft1.mh ) // 有进位位
		{
			fmtmhC = 1;
			if ( 63 ==ft1.e  )// (ft1.e范围在(-64~63),那加上进位就溢出了,则直接取63
			{
				ft.e = 63;
			}
			else
			{
				ft.e = ft1.e + fmtmhC; // 和的指数=大数的指数+1
				// 然后尾数左移一位,其中mh的最高位为进位位fmtmhC
				fmtmladd = ( ( (U32)(fmtmhadd &0x01) ) << 31 )|( fmtmladd >> 1 );
				fmtmhadd = ( (U8)( fmtmhC << 7 ) )| (U8)( ( fmtmhadd >> 1 ));

			}
		}
		else
		{
			fmtmhC = 0;
			ft.e = ft1.e ;
		}
	}
	ft.mh = fmtmhadd;
	ft.ml = fmtmladd;
	ft.s = 0;
	return ( ft );
}

myfloat MyfloatSubp( myfloat a, myfloat b ) // 正数a-正数b
{
	xdata myfloat ft;
	xdata myfloat ft1, ft2;
	xdata S8		fet;
	xdata S8      fet1;
	xdata S8		fet2;

	xdata U32		fmt2ml,fmt1ml,fmt1mlt,fmt2mlt, fmtmlsub;
	xdata U8		fmt1mh,fmt2mh,fmt1mht,fmtmhsub;
	xdata U8		fmtmlC;
	xdata S8		ftesub;
	xdata U32		fmt2mh32;				
	ft1 = a;
	ft2 = b;
	fet1 = ft1.e;
	fet2 = ft2.e;

	// 判断指数的正负
/*	if ( (ft1.e & BIT_MASKES) == BIT_MASKES )
	{
		fet1 = ( ~ft1.e + 1 ) & 0x3f; 	// 得到原码,低6位是真值位
	}
	if ( (ft2.e & BIT_MASKES) == BIT_MASKES  )		
	{
		fet2 = ( ~ft2.e + 1 ) & 0x3f; 	// 得到原码
	}
*/
	// 判断指数的正负
	if ( (ft1.e & BIT_MASKES) == BIT_MASKES )
	{
		fet1 = (S8)( 0x80 |( (U8) ( ~( (~ft1.e + 1 ) & 0x3f ) +1 ) ) ); 	// 得到原码,再求补码,由六位真值变七位真值
	}
	if ( (ft2.e & BIT_MASKES) == BIT_MASKES  )		
	{
		fet2 = (S8)( 0x80 |( (U8) ( ~( (~ft2.e + 1 ) & 0x3f ) +1 ) ) ); 	// 得到原码,再求补码,由六位真值变七位真值
	}

	if ( fet1 == fet2 )// 指数相同,尾数直接相减,有借位问题,
	{
		fmt2ml = ft2.ml;
		fmt2mh = ft2.mh;
		fmt1ml = ft1.ml;
		fmt1mh = ft1.mh;

		if ( fmt1ml < fmt2ml ) // 低32位就要有借位如a-b= 9- ( b- a)+1 ;
		{
			// 计算低32位
			fmt1mlt = fmt2ml - fmt1ml;
			fmtmlsub = (0xffffffff - fmt1mlt) +1;
			fmtmlC = 1;// 借位
		}
		else
		{
			fmtmlsub = fmt1ml - fmt2ml;
			fmtmlC = 0;
		}
		// 计算高8位
		fmt1mht = fmt1mh - fmtmlC;
		if ( fmt1mht < fmt2mh ) // 有借位,这时从指数中借了,说明ft1<ft2
		{
			// 因为ft1<ft2,则要用ft2- ft1, 负号为负,方法来算,即要算b-a,
			// 重新取得临时变量
			fmt2ml = ft2.ml;
			fmt2mh = ft2.mh;
			fmt1ml = ft1.ml;
			fmt1mh = ft1.mh;
			// 低32位				
			if (  fmt2ml <fmt1ml ) // 说明低32位就要有借位如b-a= 9- ( a-b )+1 ;
			{
				// 计算低32位
				fmt2mlt = fmt1ml - fmt2ml;
				fmtmlsub = (0xffffffff - fmt2mlt) +1;
				fmtmlC = 1;// 借位
			}
			else
			{
				fmtmlsub = fmt2ml - fmt1ml;
				fmtmlC = 0;
			}
			// 计算高8位
			fmtmhsub = fmt2mh - fmtmlC - fmt1mh;// 因为是在获知ft1尾数<ft2尾数下,到这里的,所以fmt2mh>fmt1mh或等于(则低32位一定无借位)是一定的
			// 规格化处理(尾数左移使mh最高位应为1)
			if ( 0 == fmtmhsub )
			{
				if ( 0 == fmtmlsub )// 这种情况不存在(在此条件下)
				{
					;
				}
				else
				{
					//低32位左移到最高位
					U32 fmtmlsubt;
					U8  i=1;
					fmtmlsubt=fmtmlsub;
					while ( fmtmlsubt < 0x80000000 ) // 说明低32位尾数高位不为1了 
					{
						fmtmlsubt = fmtmlsub << (i++);
					}
					//左移个数为i-1
					// 再把ml中的高8位移到mh中.
					fmtmhsub = (U8)( ( fmtmlsubt &0xff000000 ) >> 24 );
					// 这时左移个数为i-1+8
					if ( fet1 < (-64 + i +7 ) )//说明出现下溢,当0处理 
					{
						ft.s =0;
						ft.e =0;
						ft.mh =0;
						ft.ml =0;
						return ( ft );
					}
					else
					{
						ftesub = fet1 - i- 7;
						ft.s =1;
						// ftesub要处理为7位的补码
						if ( 0x80 == (ftesub &0x80) )// 负指数
						{
							ftesub=(U8)(( ftesub& 0x3f ) |0x40 );
						}

						ft.e =ftesub;
						ft.mh = fmtmhsub;
						ft.ml = fmtmlsub;
						return (ft);
					}
				}
			}
			else// fmtmhsub <>0 ,尾数的高8位不等于0
			{
				if ( 0 == fmtmlsub )// 低32位为0,只用处理高8位mh了
				{
					U8 fmtmhsubt;
					U8	i=1;
					fmtmhsubt = fmtmhsub;
					while ( fmtmhsubt < 0x80 ) // 说明高8位尾数高位不为1了 
					{
						fmtmhsubt = fmtmhsub << (i++);
					}
					//左移个数为i-1
					fmtmhsub = fmtmhsubt;//得到左移后的高8位mh结果
					if ( fet1 < (-64 + ( i -1 ) ) )//说明出现下溢,当0处理 
					{
						ft.s =0;
						ft.e =0;
						ft.mh =0;
						ft.ml =0;
						return ( ft );
					}
					else
					{
						ftesub = fet1 - ( i-1);
						ft.s =1;
						// ftesub要处理为7位的补码
						if ( 0x80 == (ftesub &0x80) )// 负指数
						{
							ftesub=(U8)(( ftesub& 0x3f ) |0x40 );
						}

						ft.e =ftesub;
						ft.mh = fmtmhsub;
						ft.ml = fmtmlsub;
						return ( ft );
					}
				}
				else // (fmtmlsub <>0 )
				{
					// 规格化处理
					// 这时需先左移mh, 再左移ml,ml左移出的位放到mh
					U32 fmtmhsubt;
					U8	i=0;
					fmtmhsubt = fmtmhsub;
					while ( fmtmhsubt < 0x80 ) // 说明高8位尾数高位不为1了 
					{
						fmtmhsubt = fmtmhsub << (++i);
					}
					//左移个数为i
					//fmtmhsub = fmtmhsubt;//得到左移后的高8位mh结果
					// 从ml 要移到mh的位 | fmtmhsub
					fmtmhsub =(U8)( fmtmhsubt | ((U8)( fmtmlsub >> ( 32 - i ))) );
					fmtmlsub = (fmtmlsub << i);
					if ( fet1 < (-64 +  i ) )//说明出现下溢,当0处理 
					{
						ft.s =0;
						ft.e =0;
						ft.mh =0;
						ft.ml =0;
						return ( ft );
					}
					else
					{
						ftesub = fet1 - i;
						ft.s =1;
						// ftesub要处理为7位的补码
						if ( 0x80 == (ftesub &0x80) )// 负指数
						{
							ftesub=(U8)(( ftesub& 0x3f ) |0x40 );
						}

						ft.e =ftesub;
						ft.mh = fmtmhsub;
						ft.ml = fmtmlsub;
						return ( ft );
					}

				}// (fmtmlsub <>0 )end 
			}// fmtmhsub <>0 ,尾数的高8位不等于0 end 
		}
		else// 高8位mh没有向指数借位,说明ft1>=ft2
		{
			fmtmhsub = fmt1mht - fmt2mh;//
			//////////////////////////////////////////////
			// 规格化处理(尾数左移使mh最高位应为1)
			///////////////////////////////////////////////
			if ( 0 == fmtmhsub )
			{
				if ( 0 == fmtmlsub )// 
				{
					ft.s=0;
					ft.e=0;
					ft.mh =0;
					ft.ml = 0;
					return ( ft );
				}
				else
				{
					//低32位左移到最高位
					U32 fmtmlsubt;
					U8  i=1;
					fmtmlsubt=fmtmlsub;
					while ( fmtmlsubt < 0x80000000 ) // 说明低32位尾数高位不为1了 
					{
						fmtmlsubt = fmtmlsub << (i++);
					}
					//左移个数为i-1
					// 再把ml中的高8位移到mh中.
					fmtmhsub = (U8)( ( fmtmlsubt &0xff000000 ) >> 24 );
					// 这时左移个数为i-1+8
					if ( fet1 < (-64 + i +7 ) )//说明出现下溢,当0处理 
					{
						ft.s =0;
						ft.e =0;
						ft.mh =0;
						ft.ml =0;
						return ( ft );
					}
					else
					{
						ftesub = fet1 - i- 7;
						ft.s =0;
						// ftesub要处理为7位的补码
						if ( 0x80 == (ftesub &0x80) )// 负指数
						{
							ftesub=(U8)(( ftesub& 0x3f ) |0x40 );
						}

						ft.e =ftesub;
						ft.mh = fmtmhsub;
						ft.ml = fmtmlsub;
						return (ft);
					}
				}
			}
			else// fmtmhsub <>0 ,尾数的高8位不等于0
			{
				if ( 0 == fmtmlsub )// 低32位为0,只用处理高8位mh了
				{
					U8 fmtmhsubt;
					U8	i=1;
					fmtmhsubt = fmtmhsub;
					while ( fmtmhsubt < 0x80 ) // 说明高8位尾数高位不为1了 
					{
						fmtmhsubt = fmtmhsub << (i++);
					}
					//左移个数为i-1
					fmtmhsub = fmtmhsubt;//得到左移后的高8位mh结果
					if ( fet1 < (-64 + ( i -1 ) ) )//说明出现下溢,当0处理 
					{
						ft.s =0;
						ft.e =0;
						ft.mh =0;
						ft.ml =0;
						return ( ft );
					}
					else
					{
						ftesub = fet1 - ( i-1);
						ft.s =0;
						// ftesub要处理为7位的补码
						if ( 0x80 == (ftesub &0x80) )// 负指数
						{
							ftesub=(U8)(( ftesub& 0x3f ) |0x40 );
						}

						ft.e =ftesub;
						ft.mh = fmtmhsub;
						ft.ml = fmtmlsub;
						return ( ft );
					}
				}
				else // (fmtmlsub <>0 )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -