由于优化原因,我考虑直接(使用内联汇编程序)调用函数“fldl”和“fist”。可悲的是,我不知道如何运行它,因为我不是汇编程序中的神。
我没有比这更进一步:
double* input;
long long output;
__asm fldl input;
__asm fist output;
由于优化原因,我考虑直接(使用内联汇编程序)调用函数“fldl”和“fist”。可悲的是,我不知道如何运行它,因为我不是汇编程序中的神。
我没有比这更进一步:
double* input;
long long output;
__asm fldl input;
__asm fist output;
最简单的可能是:
double input;
long long output;
__asm fld input
__asm fisttp output
这会进行“正常”的 double 到 long long 的转换,截断为零,就像 C 强制转换一样。但是,非常旧的(Pentium4 之前的)CPU 不支持fistpp
,因此在此类机器上您需要fistp
改用它,它使用当前的舍入模式(通常四舍五入到最接近的值)。因此,如果您想例如向 -infinity 舍入,您需要保存当前的舍入模式,将其设置为您想要的,执行fistp
并恢复舍入模式:
double input;
long long output;
unsigned short oldcw, cw;
__asm fld input
__asm fstcw oldcw
cw = (oldcw & ~0xc00) | 0x400; // round towards -infinity
__asm fldcw cw
__asm fistp output
__asm fldcw oldcw
__asm fld input
实际上会尝试读取您的指针值,就好像它是浮点值一样。如果要读取指针指向的浮点值,则必须经过两步过程:将地址读入寄存器,然后使用寄存器中的地址读取数据。在 32 位平台上,它将类似于
__asm {
mov eax, input
fld qword ptr [eax]
fistp output
}
我刚刚在VS2005中尝试过,它可以工作。(请注意,正如其他人在评论中所说,fist
不支持存储到 64-bit long long
,但fistp
确实支持。但您可能仍然需要fistp
,即弹出存储。)