【问题标题】:Why does this C code produce a double instead of a float?为什么这个 C 代码产生一个双精度而不是浮点数?
【发布时间】:2010-09-07 11:33:38
【问题描述】:

celsius = (5.0/9.0) * (fahr-32.0);

这只是 C 开发人员决定的开发选择还是有原因?我相信浮点数小于双精度数,因此可能是为了防止由于不知道使用哪种十进制格式而导致的溢出。是这个原因,还是我忽略了什么?

【问题讨论】:

    标签: c types


    【解决方案1】:

    在 K&Rv1 的日子里,鼓励交替使用浮点/双精度,因为所有浮点类型的表达式总是使用“双精度”表示进行评估,这在效率至关重要的情况下会出现问题。不带 f、F、l 或 L 后缀的浮点常量是 double 类型。并且,如果字母 f 或 F 是后缀,则常量是浮点类型。如果以字母 l 或 L 为后缀,则为 long double 类型。

    【讨论】:

      【解决方案2】:

      表达式被转换为双精度的原因是因为指定的文字默认是双精度值。如果您将等式中使用的文字指定为浮点数,则表达式将返回一个浮点数。考虑以下代码(使用 gcc 4.01 的 Mac OS X)。

      #include <stdio.h>
      int main() {
        float celsius;
        float fahr = 212;
        printf("sizeof(celsius) ---------------------> %d\n", sizeof(celsius));
        printf("sizeof(fahr) ------------------------> %d\n", sizeof(fahr));
        printf("sizeof(double) ----------------------> %d\n", sizeof(double));
        celsius = (5.0f/9.0f) * (fahr-32.0f);
        printf("sizeof((5.0f/9.0f) * (fahr-32.0f)) --> %d\n", sizeof((5.0f/9.0f) * (fahr-32.0f)));
        printf("sizeof((5.0/9.0) * (fahr-32.0)) -----> %d\n", sizeof((5.0/9.0) * (fahr-32.0)));
        printf("celsius -----------------------------> %f\n", celsius);
      }
      

      输出是:

      sizeof(celsius) ---------------------> 4
      sizeof(fahr) ------------------------> 4
      sizeof(double) ----------------------> 8
      sizeof((5.0f/9.0f) * (fahr-32.0f)) --> 4
      sizeof((5.0/9.0) * (fahr-32.0)) -----> 8
      celsius -----------------------------> 100.000008
      

      【讨论】:

        【解决方案3】:
        celsius = (5.0/9.0) * (fahr-32.0);
        

        在此表达式中,5.09.032.0doubles。这是浮点常量的默认类型 - 如果您希望它们是 floats,那么您可以使用 F 后缀:

        celsius = (5.0F/9.0F) * (fahr-32.0F);
        

        请注意,如果 fahrdouble,那么最后一个表达式的结果仍然double:正如 Vaibhav 所指出的,类型的提升方式是避免潜在的精度损失。

        【讨论】:

        • 可以说,问题是“为什么这些文字是doubles?”结合“当它适合float时,为什么表达式类型仍然是double?”
        • @Tomalak:编译器真的无法知道这个表达式的结果会“适合”一个浮点数;很有可能,即使将其塞入双精度,也会丢失一些精度。我想在表达式完全由编译时已知值组成的极端情况下,编译器可能会选择低精度结果类型......但这会使规则变得非常复杂,而不会为程序员提供任何实际价值(谁迟早要为存储选择一个明确的类型)。
        • 我知道答案是什么;我只是说..我认为这就是问题所在。 :)
        【解决方案4】:

        浮点常量应具有可用的最高精度。可以将结果分配给浮点数,而不会造成不必要的麻烦。

        【讨论】:

          【解决方案5】:

          我认为原因是为了确保可以包含任何结果。所以自然的选择是 double,因为它是最大的数据类型。

          【讨论】:

          • 自然选择是双精度的唯一原因是因为@Shog9 所说:数学中有双精度,因此它被评估为双精度。
          • A long double 可能比 double 具有更大的范围和精度,因此是候选的更大数据类型。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-12-02
          相关资源
          最近更新 更多