你是正确的 0x3FC00000 和 0x3FE00000 结果是 0x40500000
您不能将定点加法直接与浮点数一起使用。正如您在 Wikipedia 或其他任何地方所看到的,单精度浮点数格式非常简单。您需要知道的大部分内容都是在小学时学到的。
是加法还是减法?在这种情况下添加,还好最简单。排列小数点(在本例中为二进制)。
做加法。然后浮点部分根据需要进行四舍五入并归一化。
单精度是符号位、指数和隐含 1.fraction 的分数。指数是做数学运算的浮动部分,你需要将较小的数字小数位转移到以太中,直到点排成一行。然后您可以使用定点加法。我为规范化做了一个循环,但实际上是为了加法,你不能溢出超过一位(例如 0x3+0x3 = 0x6),所以正常数字的唯一规范化(不会上溢或下溢或不是nan 开始)是将其从 1x.fraction 转换为 1.fraction 或者它已经是 1.fraction 形式(用于添加两个正数)。
这里似乎有很多代码,但如果您需要做的只是添加两个
你知道的正常正数会产生一个正常的数字,你可以采取一些捷径。比我有的多。如果你不关心四舍五入,你可以采取更多。
但浮点数的加、减、乘、除并不复杂,因为您可以使用定点运算来完成任务(就像逻辑一样),您只需要准备操作数并规范化结果即可。
//float fun1 ( void )
//{
// return(1.5);
//}
//float fun2 ( void )
//{
// return(1.75);
//}
//float fun3 ( void )
//{
// return(1.75+1.5);
//}
//
//Disassembly of section .text:
//
//00000000 <fun1>:
// 0: e3a005ff mov r0, #1069547520 ; 0x3fc00000
// 4: e12fff1e bx lr
//
//00000008 <fun2>:
// 8: e59f0000 ldr r0, [pc] ; 10 <fun2+0x8>
// c: e12fff1e bx lr
// 10: 3fe00000 .word 0x3fe00000
//
//00000014 <fun3>:
// 14: e59f0000 ldr r0, [pc] ; 1c <fun3+0x8>
// 18: e12fff1e bx lr
// 1c: 40400000 .word 0x40500000
#include <stdio.h>
int main ( void )
{
unsigned int a,b;
unsigned int ea,eb;
unsigned int sa,sb;
unsigned int x,y,z;
unsigned int sxy;
a = 0x3FC00000;
b = 0x3FE00000;
//shortcut just do positive numbers
if(a&(1<<31)) return(1);
if(b&(1<<31)) return(1);
//exponents
sa=(a>>23)&0xFF;
sb=(a>>23)&0xFF;
//line up the decimal places
if(sa>sb)
{
x=a&0x007FFFFF;
x|=0x00800000;
x<<=1; //room for rounding if desired
y=b&0x007FFFFF;
y|=0x00800000;
y<<=1;
while(sa!=sb)
{
y>>=1;
sb++;
}
sxy=sa;
}
else
{
x=a&0x007FFFFF;
x|=0x00800000;
x<<=1;
y=b&0x007FFFFF;
y|=0x00800000;
y<<=1;
while(sa!=sb)
{
y>>=1;
sa++;
}
sxy=sb;
}
z=x+y;
z++; //round up
while(z&0xFE000000) //should just be if(0x02000000)
{
z>>=1;
sxy++;
}
z>>=1; //remove sticky bit
z&=0x007FFFFF;
z|=sxy<<23;
printf("0x%08X\n",z);
return(0);
}
在开始之前了解这两个数字,我们可以作弊并采取一些捷径,而不必费心四舍五入。
#include <stdio.h>
int main ( void )
{
unsigned int a,b;
unsigned int ea,eb;
unsigned int sa,sb;
unsigned int x,y,z;
unsigned int sxy;
a = 0x3FC00000;
b = 0x3FE00000;
//shortcut already know they are positive numbers
//exponents I already know are the same
sxy=(a>>23)&0xFF;
//line up the decimal places (already aligned)
x=a&0x007FFFFF;
x|=0x00800000;
y=b&0x007FFFFF;
y|=0x00800000;
z=x+y;
if(z&0x02000000)
{
z>>=1;
sxy++;
}
z&=0x007FFFFF;
z|=sxy<<23;
printf("0x%08X\n",z);
return(0);
}
在 asm 中编写代码并不难。