浮点运算的编程风格

Programming style in Float operations

本文关键字:风格 编程 浮点运算      更新时间:2023-10-16

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

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

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

或者类似于写一个条件有and 1==1 .

p。S:在某些情况下,某些变量(除了ratio)被赋值为非Float/double值,如长或整型。

C/c++

当一个或多个变量top, bottom等为double类型时,乘以1.0是没有意义的。你应该把它去掉,因为它没有任何用处。当所有变量都是float类型时,乘以double字面值1.0将强制使用双精度算术对表达式求值。

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

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

德尔福

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

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

c++中,经验法则是

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

请记住,operationoperator非常相关。操作的顺序由运算符优先级。

c++中基本操作的优先级是很自然的。

  • */出现在+-之前
  • 表达式在()内优先发生

所以如果你有

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

记得

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

在c++中,1.0double,因此它会提高计算的精度。如果这是意图,那么明确地转换为double会更清楚。如果这是目的,它在表达式中也不是一个理想的位置(top-bottom将在精度增加之前求值)。

可能还有其他原因,比如常数原来是2.0,但随着时间的推移被微调为1.0,隐藏了这个乘法的原始原因。从你的计算来看,我认为情况并非如此。