【发布时间】:2016-02-16 22:52:44
【问题描述】:
以下代码应将 正(单精度)浮点数量化为 32 位整数。
由于正数范围仅包含2^31 - 1(离散)级别,代码将样本乘以该值,并将结果四舍五入为整数:
mov eax, 0x7FFFFFFF // eax = 2^31 - 1
cvtsi2ss xmm1, eax // convert eax to float --> xmm1
movss xmm0, [sample] // where 'sample' is of type float
mulss xmm0, xmm1 // Get sample's quantum into xmm0
cvtss2si eax, xmm0 // Round quantum to the nearest integer --> eax
问题是:对于sample 值1.0f,最终结果(eax 值)是 0x80000000 = 2^31,超出范围。
预期结果为1.0 x (2^31 - 1) = (2^31 - 1) = 0x7FFFFFFF。
而且,这个值实际上是 -2^31 的 2 的补码表示(注意减号)。
我在这里错过了什么?
{ 正在使用 MSVC2010 进行测试。 } `
【问题讨论】:
-
0x7FFFFFFF 转换为浮点数时舍入到 2147483648 开头
-
是的,你应该试试双精度。
-
@harold,所以基本上,你是说
xmm1拥有2^31的浮点表示,而not 是2^31 - 1? -
单精度是 32 位,尾数只有 24 位,所以是的,你不能指望能够在不损失精度的情况下将 32 位整数塞入其中。
-
只是一个附录。如果使用 MSVC 2010,您应该能够编译/汇编它,并使用调试器逐步完成,并在 cvtsi2ss 和每个后续指令之后查看包括 XMM1 在内的寄存器。您可能已经发现 xmm1 中填充了什么浮点值。
标签: assembly x86 sse masm masm32