【问题标题】:How to print a double data type in C [duplicate]如何在 C 中打印双精度数据类型 [重复]
【发布时间】:2018-11-15 12:09:13
【问题描述】:

为什么在 C 中,当我使用 %f 打印双精度类型变量时,它会显示 8.000000... 但这不是期望的结果。我想要一个像 8.5000 这样的结果,我怎样才能做到这一点?

 int main(){
     int i, j;
      double k;
      i=8; j=9;
      k = (i+j)/2;
      printf("%f", k);
    }

【问题讨论】:

  • int 除以 int 得到(四舍五入的)int
  • 试试k = (i+j)/2; ==> k = (i+j)/2.0;
  • @MichaelButscher:“四舍五入”==>“截断”
  • @pmg 没错,当然

标签: c floating-point


【解决方案1】:

问题不在于格式说明符,而在于算术运算。

说出来

 k = (i+j)/2;

其中,ij2 - 都是 ints,您正在执行整数除法,然后将结果存储在 double 中。对于整数除法,

[..] 当整数被除法时,/ 运算符的结果是代数商,其中任何小数部分被丢弃 [...]

通常称为“向零截断”。为避免这种情况发生,您需要强制执行浮点运算,方法是将操作数之一强制或强制转换为 double(或 float)。类似的东西

k = ((double)i+j)/2;

或者,

k = (i+j)/2.0;  //2.0 is of type double 

这里的重点是,如果在运算中,其中一个操作数的排名较高(doublefloat 的排名高于int),则所有操作数将首先转换为较高的rank,然后执行操作,结果将是排名较高的类型。

【讨论】:

  • 非常感谢您的解释,我现在明白了
【解决方案2】:

由于 i 和 j 是 int,结果首先被转换为 int。这会降低精度。显式转换为 double k = (double)(i+j)/2

【讨论】:

  • 我会说结果是一个整数,因为只会执行整数运算。那时不涉及演员表。
【解决方案3】:

评论是正确的。为了更好地理解这一点: C 表达式在“一个块”中进行评估。您的作业(i+j)/2 的右侧是一个完整的表达式。由于它只包含整数值,因此所选择的算术也将是整数类型(这会导致结果被截断),创建临时整数值(对您不可见),然后将其分配给double

您需要使表达式中的至少一个值成为double(或float),然后编译器会将所有算术提升为浮点数,并且临时值也将是浮点类型。

如果你的表达式中没有常量,你也可以使用强制类型转换:

((float)i+J)/2

3 个项目中的哪一个获得演员表并不重要,只要一个就足够了。

【讨论】:

  • creating temporary integer value (invisible to you), which is then assigned to a double ---> truncation.是这样吗?
  • @Sourav Ghosh AFAIK 是的。
  • 我不这么认为。如果您试图表示整数除法的结果倾向于截断结果 - 我同意。但是将整数存储在 double 中会导致截断 - 你能引用一些来源吗?
  • 好吧,如果我看一下反汇编,算术是使用整数加法和右移来执行的。在 x86-64 处理器上,对双精度的赋值是 cvtsi2sd(从 int 转换为 float)。所以,是的,我会说保存在 gp 寄存器中的中间值确实是一个临时整数。执行算术运算时已经发生截断。
  • 啊,我明白我们的误会了。我这边措辞不好,对不起。我将编辑我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-05
  • 2019-05-22
  • 2016-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多