Floating point 什么';将有符号单精度浮点舍入为最接近的整数是一种有效的方法吗?

Floating point 什么';将有符号单精度浮点舍入为最接近的整数是一种有效的方法吗?,floating-point,rounding,msp430,Floating Point,Rounding,Msp430,这对于我在MSP430上使用编译器提供的浮点加法支持库的应用程序来说是低效的 我在想,这种特殊的“最近整数”舍入可能有一个聪明的“技巧”,通过直接“位旋转”浮点表示来避免普通的浮点加法,但我还没有找到类似的技巧。有人能提出这样一个技巧来取整IEEE 754 32位浮点吗?通过位操作进行转换很简单,下面的C代码演示了这一点。根据MSP430上关于数据类型的注释,代码假定int包含16位,而long32位 我们需要一种尽可能有效地将浮点的位模式转换为无符号长的方法。此实现使用联合为此,您的平台可能有

这对于我在MSP430上使用编译器提供的浮点加法支持库的应用程序来说是低效的


我在想,这种特殊的“最近整数”舍入可能有一个聪明的“技巧”,通过直接“位旋转”浮点表示来避免普通的浮点加法,但我还没有找到类似的技巧。有人能提出这样一个技巧来取整IEEE 754 32位浮点吗?

通过位操作进行转换很简单,下面的C代码演示了这一点。根据MSP430上关于数据类型的注释,代码假定
int
包含16位,而
long
32位

我们需要一种尽可能有效地将
浮点
的位模式转换为
无符号长
的方法。此实现使用
联合
为此,您的平台可能有更有效的特定于机器的方法,例如内在的。在最坏的情况下,使用
memcpy()
复制字节

只有几个案例需要区分。我们可以检查
float
输入的指数字段来区分它们。如果参数太大或为NaN,则转换失败。一种约定是在这种情况下返回最小的负整数操作数。如果输入小于0.5,则结果为零。在消除这些特殊情况后,我们只剩下那些需要少量计算才能转换的输入

对于足够大的参数,
float
始终是一个整数,在这种情况下,我们只需要将尾数模式移动到正确的位位置。如果输入太小而不能成为整数,我们将转换为32.32定点格式。然后,舍入基于最高有效分数位,对于tie,也基于最低有效整数位,因为tie必须舍入为偶数

如果假设平局案例总是从零开始舍入,那么代码中的舍入逻辑将简化为

float input = whatever;
long output = (long)(0.5f + input);
下面是实现上述方法的
float\u to\u long\u round\u nearest()
,以及一个测试框架,该框架对该实现进行了详尽的测试

#包括
#包括
#包括
长浮球到最近的长浮球(浮球a)
{
易变联{
浮动f;
无符号长i;
}cvt;
未签字的长r、ia、t、expo;
cvt.f=a;
ia=cvt.i;
世博会=(ia>>23)&0xff;
如果(expo>157){/*量级太大(>=2**31)或NaN*/
r=0x8000000微升;
}否则,如果(expo<126){/*量级太小(<0.5)*/
r=0x00000000UL;
}否则{
int shift=世博会-150;
t=(ia&0x007fffffUL)| 0x00800000UL;
如果(expo>=150){/*参数是整数,则向左移位*/
r=t>(-shift);
t=0x80000000UL)|((t=0x80000000UL)和(r&1));
}
如果((长)ia<0){/*如果参数为负,则否定结果*/
r=-(长)r;
}
}
返回(长)r;
}
长参考(浮点a)
{
返回(长)rintf(a);
}
内部主(空)
{
易变联{
浮动f;
无符号长i;
}精氨酸;
长res,ref;
参数i=0x00000000UL;
做{
res=最接近的浮点数到长整数(arg.f);
ref=参考(参数f);
如果(res!=ref){
printf(“arg=%08lx%15.8e res=%08lx ref=%08lx\n”,
参数i,参数f,res,ref);
返回退出失败;
}
arg.i++;
}while(arg.i);
返回退出成功;
}

所以您正在寻找
long float\u to\u long\u round\u nearest(float)
函数实现,对吗?在您的平台上,
long
包含多少位?转换必须能够正确处理多大范围的
浮点
操作数?应如何处理平局案件:平局还是平局?似乎理想的转换过程不应该涉及浮点操作,因为这些操作是在这个平台上模拟的?我认为编程语言是C?软件浮点运算速度慢,周期长。绕过慢速软件浮点的唯一方法是使用硬件浮点。使用直接在位级表示上操作的位操作方法将IEEE-754
float
转换为
long
当然是可能的,但有一个精确的规范会有所帮助。今天晚些时候我应该可以为这个编写一些C代码。在MSP430上,
int
/
long
有16/32位。但是,
类型是受支持的。@CL感谢您的澄清,我将相应地修改我的代码。这太棒了!这正是我所希望的,与我的应用程序使用标准C库“+0.5f”相比,这是一个显著的改进。非常感谢。
r = r + (t >= 0x80000000UL);