📄 myfloat.c
字号:
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 + -