【问题标题】:Programming style in Float operations浮点运算中的编程风格
【发布时间】:2011-12-16 09:55:31
【问题描述】:

我碰巧遇到了一些类似的编程风格,主要是在 Float 或 Double 操作时。

ratio = 1.0 * (top - bottom) / (right - left);  

所有涉及的变量都是浮点数。
1.0 乘以结果有什么意义?
根据我的想法,乘以 1.0 是一些额外的负担。因为结果不会改变。

或者写一个有and 1==1的条件是不是类似。

P.S:在某些情况下,某些变量(比率除外)被分配给非浮点/双精度值作为长整数或整数。

【问题讨论】:

  • 什么语言?什么平台?
  • @Oded 在 C++,Delphi 中看到过这个。
  • real factor 1.0 导致编译器将表达式的一部分视为实数(否则可以是整数),仅此而已
  • 将您的语句拆分为three-address code 以找出可能发生类型转换的位置。 [Aho, Sethi, Ullman] 了解更多详情。
  • @user539484:它不依赖于三地址码,而是依赖于语言规则(特别是优先顺序和自动类型转换/提升)。

标签: c++ delphi coding-style


【解决方案1】:

C/C++

topbottom 等变量中的一个或多个是double 类型时,乘以1.0 是没有意义的。您应该简单地删除它,因为它没有任何用途。当所有变量都是 float 类型时,乘以 double 文字 1.0 会强制使用双精度算术计算表达式。

另一方面,当所有变量都是整数时,乘以1.0 会强制使用浮点运算执行计算。如果没有乘法,则将使用整数算术执行计算,这会产生不同的结果。

我的猜测是代码最初使用整数并且需要1.0。在某个时间点,代码被更改为使用浮点变量,但现在的虚假乘法并没有被删除。

德尔福

如果您在 Delphi 代码中看到这样的表达式,那么您应该简单地删除乘法。除法运算符的存在强制将表达式作为浮点表达式进行计算。

Delphi 表达式求值的规则与 C 和 C++ 略有不同。在 C 和 C++ 中,单个符号 / 用于整数和浮点除法,表达式的上下文决定了使用哪种除法形式。在 Delphi 中,/ 是浮点除法,div 是整数除法。

【讨论】:

  • 我认为最后一部分是模棱两可的:division is a separate operator in Delphi, div and the / operator always means floating point division。我提议division is a separate operator in Delphi (namely div), the / operator always means floating point division
  • 是的,这比我的提议要好:)
【解决方案2】:

在 C++ 中,经验法则是

如果运算涉及到浮点型,则两个操作数都转换为浮点型(结果为浮点型)

请记住,operationoperator 非常相关。并且操作的顺序由 operator precedence.

C++ 中基本操作的优先级是很自然的 w.r.t.数学:

  • *,/ 发生在 +,- 之前
  • () 中的表达式首先发生

如果你有

float f = 1.0f + 1 / 2;

// then `f` will be `1.0f`, because

int   sub = 1 / 2     ;  // <- an integer division, happens first and gives 0
float f   = 1.0f + sub;  // <- 0 because the division result was evaluated first

最终结果是float 类型,因为最后的操作是float + int

另一个例子,涉及大括号表达式:

float f = (1.0f + 1) / 4;

// `f` will be `0.5` this time. The braced expressions happens first:

float sub = 1.0f + 1;  // float + int = float
float f   = sub / 4;   // float / int = float

这里需要注意的是,44.0f 的转换发生在操作之前,就像在这个示例程序集中一样:

// [mnemomic] [what]+ [target]
fload 1.0f, float_register_0
fload 1,    float_register_1
fadd  float_register_0, float_register_1, float_register_2 // sub is in [2]
fload 4,    float_register_3                               // 4 is in [3]
fdiv  float_register_2, float_register_3, f                // [2]/[3] -> f

记住

如果运算涉及到浮点型,则两个操作数都转换为浮点型(结果为浮点型)

【讨论】:

    【解决方案3】:

    在 C++ 中,1.0double,因此它会提高计算的精度。如果这是有意的话,直接明确地转换为double 会更清楚。如果这是意图,它在表达式中的位置也不理想(top-bottom 将在精度增加之前进行评估)。

    虽然可能还有其他原因,例如常数曾经是 2.0,但随着时间的推移被微调为 1.0,隐藏了这种乘法的原始原因。从您执行的计算来看,我认为情况并非如此。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-15
      • 1970-01-01
      • 2012-10-15
      • 1970-01-01
      • 2016-08-23
      • 2018-06-23
      • 2018-11-14
      相关资源
      最近更新 更多