我知道浮点不准确,但我需要绕过它们。
所以,我需要进行图遍历,并通过将所有节点放入堆栈,向所有邻居添加路由,然后向所有非邻居添加大路径,最后进行图遍历。经历并找到最佳路线。它适用于从邻居创建的路由,但它会在使用大数字创建的路由上中断。
这是相关的代码部分。
这里分配了大型路线。
movsd xmm0, [big]
mov [r11+rax+TAR], r9
movsd [r11+rax+DIS], xmm0
mov [r11+rax+HOP], r9
在此进行比较,以查看是否找到了更好的路线。
ucomisd xmm0, xmm2
ja bMBD
jmp eMBD
bMBD:
mov rax, [r8+ROT]
mov [rax+r13+HOP], r11
movsd [rax+r13+DIS], xmm2
eMBD:
上面的代码块是问题所在,以下是我认为代码正在做的细分。
D要求D提供更好的路线,但没有任何反应:好。
D问A,找到一个并计算距离为3.3 + 5.4 = 8.7,它更好并取代它的当前路线:好。
D问B,找到一个距离为8.7 + 0 = 8.7的人。由于某种原因,这被认为是更好的,它的路线被取代:坏。
那么,为什么ja
条件返回8.7> 8.7,但仅限于他们的距离初始化为大数的路线(我尝试减小数字的大小,但是产生了相同的结果)?
谢谢。
答案 0 :(得分:3)
舍入差异是浮点数学中的生命现实。这解释为here。
如果您只需要找到任何最佳路线之一,那么我在3.3 + 5.4 > 8.7 + 0.0
中看到没有问题;其中一条路线都没问题。
如果您需要检索共享相同最佳距离的所有路由,那么我同意您确实需要3.3 + 5.4
等于8.7 + 0.0
。
有几种方法可以实现这一目标;见下文。对于示例代码,我将使用伪代码而不是汇编,因为此问题并非特定于任何语言。
如果数字的差值的绝对值小于某个小数(例如0.001),则认为数字相等。 这意味着比较逻辑变得稍微复杂一些。 而不是:
if x < y then
return LESS_THAN
elseif x > y then
return GREATER_THAN
else
return EQUAL
你会这样做:
epsilon = 0.001
if x < y - epsilon then
return LESS_THAN
elseif x > y + epsilon then
return GREATER_THAN
else
return EQUAL
这比听起来容易;只需将所有内容乘以某个因子,该因子将消除每个数字的小数部分,并根据整数而不是浮点数执行所有计算。
对于距离NNNN.N
(即小数点后面不超过一位十进制数),此因子为10.
所以而不是:
routeA = 3.3 + 5.4
routeB = 8.7 + 0.0
if routeA > routeB then ...
你会这样做:
routeA = 33 + 54
routeB = 87 + 0
if routeA > routeB then ...