0

由于优化原因,我考虑直接(使用内联汇编程序)调用函数“fldl”和“fist”。可悲的是,我不知道如何运行它,因为我不是汇编程序中的神。

我没有比这更进一步:

double* input;         
long long output;

__asm fldl input;      
__asm fist output;
4

2 回答 2

1

最简单的可能是:

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
于 2012-11-30T17:43:05.917 回答
1

__asm fld input实际上会尝试读取您的指针值,就好像它是浮点值一样。如果要读取指针指向的浮点值,则必须经过两步过程:将地址读入寄存器,然后使用寄存器中的地址读取数据。在 32 位平台上,它将类似于

__asm {
  mov eax, input
  fld qword ptr [eax]
  fistp output
}

我刚刚在VS2005中尝试过,它可以工作。(请注意,正如其他人在评论中所说,fist不支持存储到 64-bit long long,但fistp确实支持。但您可能仍然需要fistp,即弹出存储。)

于 2012-11-30T16:53:30.167 回答