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

编译器会将除法优化为乘法吗

督宏旷
2023-03-14

根据这个问题,浮点除法与浮点乘法。由于某些原因,除法比乘法慢。

如果可能的话,编译器通常会用乘法代替除法吗?

例如:

float a;
// During runtime a=5.4f
float b = a/10.f;

会是:

float a;
// During runtime a=5.4f
float b = a*0.1f;

如果它被认为是编译器可靠的问题,我使用的是VS2013默认编译器。但是,如果我得到一个通用的答案就好了(这种优化的理论有效性)

共有1个答案

太叔望
2023-03-14

不可以,对于一般情况,编译器不允许这样做:由于倒数的表示错误,这两个操作可能会产生不完全相同的结果。

在您的示例中,< code>0.1没有精确表示为< code>float的形式。这导致乘以< code>0.1和除以< code>10的结果不同:

float f = 21736517;
float a = f / 10.f;
float b = f * 0.1f;
cout << (a == b) << endl; // Prints zero

演示。

注意:正如njuffa在下面的评论中正确指出的,在某些情况下,编译器可以对一组广泛的数字进行一些优化,如本文所述。例如,乘以或除以2的幂相当于添加到IEEE-754浮点数表示的指数部分。

 类似资料:
  • 如果我写 大多数C编译器是否足够聪明,能够将1或-1的乘法优化成更快的运算(无操作或求反)?

  • 有问题的代码如下: 编译器会优化它吗?根据C-Standard(如果我理解正确的话),第二个操作数必须提升为;因此乘法必须使用FPU(或fp仿真)完成。 从理论上讲,该操作可以在正常的硬件寄存器中完成,只需添加一个即时的(并且可能是溢出检查)。是否允许编译器执行此优化?是否有已知的编译器这样做?如果是这样,他们是否也会识别该表达式 这是避免有关隐式转换的静态代码检查器警告所必需的? 补充一下:我知

  • 问题内容: 假设我在C代码中有类似的内容。我知道您可以使用a 代替,以使编译器不对其进行编译,但是出于好奇,我问编译器是否也可以解决此问题。 我认为这对于Java编译器来说更为重要,因为它不支持。 问题答案: 在Java中,if内的代码甚至都不是已编译代码的一部分。它必须编译,但不会写入已编译的字节码。它实际上取决于编译器,但我不知道没有对它进行优化的编译器。规则在JLS中定义: 优化的编译器可能

  • 问题内容: 问题说明了一切。有人知道以下内容吗? …被优化成? 编译器会这样做吗?(我的兴趣在于GCC)。在某些情况下会这样做吗?在其他情况下却不会呢? 我真的很想知道,因为每次我写一个像这样可以优化的除法运算时,我都会花些精力思考是否浪费一秒钟宝贵的时间去做一个足以满足需要的除法运算。 问题答案: 即使g++ -O0(是,-O0!),也会发生这种情况。您的函数编译为: 请注意shrq $6,右移

  • 我经常遇到这种情况。乍一看,我认为,“这是糟糕的编码;我正在执行一个方法两次,必然会得到相同的结果。”但想到这里,我不得不怀疑编译器是否像我一样聪明,并能得出相同的结论。 编译器的行为是否取决于 方法的内容?假设它看起来像这样(有点类似于我现在的真实代码): 除非对这些对象来自的任何存储进行处理不当的异步更改,否则如果连续运行两次,肯定会返回相同的内容。但是,如果它看起来像这样(为了论证而无意义的

  • 在 C 或 C 中,如果编译器遇到一个 循环,其中计数器从 计数到 n, n 是一个变量(不是函数调用,也不是常量),编译器是否会通过检查变量 (绑定变量)是否会在循环期间更改(访问写入, 例如: 可以是循环前计算的字符串的长度),通过优化这里,我的意思是将其值复制到寄存器以避免内存访问? 下面是一个示例: 编译器会注意到这一点并对其进行优化吗?