我正在寻找一种有效的算法,该算法可以计算整数的“算术右移”,该算法舍入到最接近的整数,并具有“半舍入到零”行为。答案可以是对此类算法或其实现的正确描述(例如在汇编或 C 中)。 你可以假设:
整数大小为 32 位二进制补码格式用于表示负值
这是C语言的原型:
int asrz(int x, int n);
舍入方法详情
算法应该计算
Y = X >> N
真实结果四舍五入为最接近的整数。作为打破平局的规则,如果小数部分为 0.5,则四舍五入为零。以下是一些例子:
0 >> 1 = 0
1 >> 1 = 0 (0.5)
2 >> 1 = 1
3 >> 1 = 1 (1.5)
...
2 >> 2 = 0 (0.5)
3 >> 2 = 1 (0.75)
4 >> 2 = 1
5 >> 2 = 1 (1.25)
6 >> 2 = 1 (1.5)
7 >> 2 = 2 (1.75)
...
12 >> 3 = 1 (1.5)
13 >> 3 = 2 (1.625)
对于负输入值,结果围绕零对称:
-1 >> 1 = 0 (-0.5)
-2 >> 1 = -1
-3 >> 1 = -1 (-1.5)
...
-2 >> 2 = 0 (-0.5)
-3 >> 2 = -1 (-0.75)
-4 >> 2 = -1
-5 >> 2 = -1 (-1.25)
-6 >> 2 = -1 (-1.5)
-7 >> 2 = -2 (-1.75)
...
-12 >> 3 = -1 (-1.5)
-13 >> 3 = -2 (-1.625)
备注
该行为与大多数指令集中可用的 ASR 指令不同:
对于负输入值,四舍五入为 -无穷大(例如 -7 ASR 1 = -4)。
这可以很好地移植到 ARM,尽管在 ARM64 和没有进位标志(例如 RISC-V)的架构上,这样做比较烦人。 您必须手动计算进位,然后将其相加。