在三维空间中写两个点之间的函数计算距离。 gdb会话:
48 mulsd xmm1, xmm0
(gdb) p/f $xmm0
$5 = {v4_float = {5.08412027, 0, 0, 0}, v2_double = {5.3576676113063418e-315, 0}, v16_int8 = {29, -79, -94, 64, 0 <repeats 12 times>}, v8_int16 = {-20195, 16546, 0, 0, 0,
0, 0, 0}, v4_int32 = {5.08412027, 0, 0, 0}, v2_int64 = {5.3576676113063418e-315, 0}, uint128 = 3.9528689422358843932327897004554155e-4942}
(gdb) p/f $xmm1
$6 = {v4_float = {5.08412027, 0, 0, 0}, v2_double = {5.3576676113063418e-315, 0}, v16_int8 = {29, -79, -94, 64, 0 <repeats 12 times>}, v8_int16 = {-20195, 16546, 0, 0, 0,
0, 0, 0}, v4_int32 = {5.08412027, 0, 0, 0}, v2_int64 = {5.3576676113063418e-315, 0}, uint128 = 3.9528689422358843932327897004554155e-4942}
(gdb) n
49 movsd xmm0, xmm2
(gdb) p/f $xmm1
$7 = {v4_float = {0, 0, 0, 0}, v2_double = {0, 0}, v16_int8 = {0 <repeats 16 times>}, v8_int16 = {0, 0, 0, 0, 0, 0, 0, 0}, v4_int32 = {0, 0, 0, 0}, v2_int64 = {0, 0},
uint128 = 0}
(gdb) p/f $xmm0
$8 = {v4_float = {5.08412027, 0, 0, 0}, v2_double = {5.3576676113063418e-315, 0}, v16_int8 = {29, -79, -94, 64, 0 <repeats 12 times>}, v8_int16 = {-20195, 16546, 0, 0, 0,
0, 0, 0}, v4_int32 = {5.08412027, 0, 0, 0}, v2_int64 = {5.3576676113063418e-315, 0}, uint128 = 3.9528689422358843932327897004554155e-4942}
目的地登记册中奇怪的是零。 你有什么建议如何在没有得到零的情况下进行乘法运算?
答案 0 :(得分:1)
由于下溢,你得零。对于x <1,x ^ 2 更接近为零。平方数字使其远离1。
5.3e-315的幅度小于sqrt(smallest denormal double)
,因此将其平方后得零。 (注意DBL_MIN
是最小的归一化正双,但非正规可以更小。)
使用随机垃圾值测试FP数学不是一个好主意,除非你确定你知道指令的作用是什么&#34;常规&#34;像3.14159这样的值... FP数学已经很难了:
[浮点]数学很难。
你只是不会相信它是多么巨大,令人难以置信的难度。我的意思是,你可能认为很难计算出来自芝加哥和洛杉矶的火车何时发生碰撞,但这只是花生到浮点数学上。
- 布鲁斯道森的出色series of articles on tricky FP math stuff。
使用p $xmm0.v2_double
仅打印xmm0
的双重解释。它在屏幕上的噪音要小得多。
此外,您应该使用MOVAPD(或MOVAPS)在寄存器之间进行复制。如果要与目标寄存器的上部元素合并,则仅使用MOVSD。