当前位置: 首页 > 知识库问答 >
问题:

使用乘法执行整数除法[重复]

翁翰
2023-03-14

查看编译器生成的x86程序集,我注意到(无符号)整数除法有时被实现为整数乘法。这些优化似乎遵循以下形式:

value / n => (value * ((0xFFFFFFFF / n) + 1)) / 0x100000000

例如,执行除以9:

12345678 / 9 = (12345678 * 0x1C71C71D) / 0x100000000

除以3将使用与<code>0x55555555 1</code>的乘法,依此类推。

利用< code>mul指令将结果的高部分存储在< code>edx寄存器中这一事实,可以使用与幻值的单次乘法来获得除法的最终结果。(尽管这种优化有时在最后与逐位移位结合使用。)

我想了解一下这实际上是如何工作的。这种方法什么时候有效?为什么必须将1添加到我们的“神奇数字”中?

共有1个答案

钱浩荡
2023-03-14

该方法称为“除以不变乘法”。

你看到的常量实际上是倒数的近似值。

因此,不是计算:

N / D = Q

你做这样的事情:

N * (1/D) = Q

其中1/D是可以预先计算的倒数。

从根本上说,倒数是不精确的,除非<code>D<code>是2的幂。所以会有一些舍入误差。您看到的<code>1

最常见的例子是除以3:

N / 3 = (N * 0xaaaaaaab) >> 33

其中< code > 0x aaaaaaab = 2^33/3 ^ 1 。

这种方法将推广到其他除数。

 类似资料:
  • 考虑处理可能有数百位数的整数的需要。让我们称之为“超长”整数。显然,它们不能使用int或long int等数据类型进行存储。“超长”整数可以作为用户的输入逐位读入,并存储在一个数组中,超长整数的每个数字都占据数组中的一个位置。问题涉及到将两个正的“超长”整数作为用户的逐位输入。每个数字由用户作为字符输入。正“超长”整数的结尾由$符号的输入和存储表示。 这里,您可以假设正超长整数将占用的最大位数是2

  • 3、ASCII码乘调整指令AAM(AsciiAdjust After Multiplication) 该指令是用于调整寄存器AL之值,该值是由二个单BCD码字节用无符号乘指令MUL所得的积。其调整规则如下: AH←AL/10(商),AL←AL%10(余数) 指令的格式:AAM 受影响的标志位:PF、SF和ZF(AF、CF和OF等都是无定义) 例如: MOV AL,9 MOV BL, 8 MUL B

  • 我写了一个代码,在两个数相除后求出商,但不使用乘法、除法或mod运算符。 我的代码 我的代码通过了像分红=-1、除数=1或分红=1和除数=-1这样的测试用例。但是它不能通过像分红=--2147483648和除数=-1这样的测试用例。但是当两个输入都是负数时,我有一个if语句。 当我的输入为-2147483648和-1时,它返回零。我调试了代码,发现它无法到达while循环的内部语句。它只是检查wh

  • 问题内容: 在 JavaScript中 ,如何获取: 给定整数进入另一个整数的整数倍? 其余的? 问题答案: 对于一些数字和一些除数,将商()和余数()计算为:

  • 问题内容: 您能帮我弄清楚这个Python部门吗 基数= 12.0 高度= 16 面积= 1/2 基础高度 解决方案对此表示 面积=(基数*高度)/ 2; 让我感到困惑的是1/2将是浮点数,而Python仅显示0而不是0.5,为什么在这种情况下解决方案显示/ 2 … 问题答案: Python2.7自动使用运算符作为整数(整数)除法,该运算符将始终产生整数。 例如: 1/2 = 0 3/4 = 0

  • 霍尼韦尔DPS8计算机(和其他计算机)有一条“除分数”指令: “此指令将71位分数除数(包括符号)除以36位分数除数(包括符号),形成36位分数商(包括符号)和36位分数余数(包括符号)。余数的第35位对应于被除数的第70位。除非余数为零,否则余数符号等于被除数符号。” 据我所知,这是整数除法,小数点在左边。 (我确实在白天将整数数学进行了前移,但我对这些技术的记忆在时间的迷雾中消失了。) 要在D