如何在汇编中舍入为整数而不分支?

问题描述 投票:0回答:5

如何在 Assembly 中将实数舍入为最接近的整数?这里不允许使用分支。

例如,

195 * .85 = 165.75
。通常,我会将 195 乘以比例因子 (100),然后相乘,然后除以比例因子。这会给我 165。我怎样才能得到 166?

assembly rounding branchless
5个回答
7
投票

例如,195 * .85 = 165.75。通常,我会将 195 乘以比例因子 (100),然后相乘,然后除以比例因子 因素。这会给我 165。我怎样才能得到 166?

通常,您会使用两倍比例因子的幂和移位,而不是乘法和除法;我想现在除法和乘法的成本与许多架构上的移位成本相同,您可能更关心保持一定的精度。

无论如何,正如halex所建议的那样,你应该在除法之前添加0.5。最终效果是,如果小数部分已经是 0.5 或更大,您将进入整数部分。如果没有的话就没有携带。

所以:

195 * 100 = 19500
19500 * 0.85 = 16575
16575 + 50(即0.5)= 16625
16625 / 100 = 166


3
投票

假设只给你整数,并且只是告诉你其中一个整数需要使用比例因子像小数一样处理......那么你可以通过使用两倍于你需要的比例因子来做到这一点。因此,您使用 200,而不是 100。这将导致结果的最后一位为 1 或 0,具体取决于您是否向上舍入。

所以在c风格中它看起来像这样

result = (195 * 85) / (100 / 2);
add = result & 1;
result = result / 2 + add;

如果您不应该向上舍入(即向下舍入),那么“添加位”将为 0。否则,如果您应该向上舍入,“添加位”将为 1。

我认为这应该为您提供将其正确转换为汇编所需的伪代码。


3
投票

在 x86 汇编中,有 FRNDINT 指令。


-2
投票

整数没有小数位,因此它已经是整数了。


-2
投票

对于正数和负数,asm 中有 6 个字符串。

double round(double x) {
  return (long)(x + 0.5 + (*(long*)&x >> 63));
}
© www.soinside.com 2019 - 2024. All rights reserved.