我假设需要截断,就像在“C”中写i = (int)f一样。
如果你有 SSE3,你可以使用:
int convert(float x)
{
int n;
__asm {
fld x
fisttp n // the extra 't' means truncate
}
return n;
}
或者,使用 SSE2(或在 x64 中内联汇编可能不可用),您可以使用几乎一样快:
#include <xmmintrin.h>
int convert(float x)
{
return _mm_cvtt_ss2si(_mm_load_ss(&x)); // extra 't' means truncate
}
在较旧的计算机上,可以选择手动设置舍入模式并使用普通的fistp 指令执行转换。这可能仅适用于浮点数组,否则必须注意不要使用任何会使编译器更改舍入模式的构造(例如强制转换)。这样做是这样的:
void Set_Trunc()
{
// cw is a 16-bit register [_ _ _ ic rc1 rc0 pc1 pc0 iem _ pm um om zm dm im]
__asm {
push ax // use stack to store the control word
fnstcw word ptr [esp]
fwait // needed to make sure the control word is there
mov ax, word ptr [esp] // or pop ax ...
or ax, 0xc00 // set both rc bits (alternately "or ah, 0xc")
mov word ptr [esp], ax // ... and push ax
fldcw word ptr [esp]
pop ax
}
}
void convertArray(int *dest, const float *src, int n)
{
Set_Trunc();
__asm {
mov eax, src
mov edx, dest
mov ecx, n // load loop variables
cmp ecx, 0
je bottom // handle zero-length arrays
top:
fld dword ptr [eax]
fistp dword ptr [edx]
loop top // decrement ecx, jump to top
bottom:
}
}
请注意,内联程序集仅适用于 Microsoft 的 Visual Studio 编译器(可能还有 Borland),必须将其重写为 GNU 程序集才能使用 gcc 进行编译。
但是,具有内在函数的 SSE2 解决方案应该非常便携。
其他舍入模式可以通过不同的 SSE2 内在函数或手动将 FPU 控制字设置为不同的舍入模式。