6

谁能帮我为什么 x2 打印为零。我猜由于浮点表示 X1 被四舍五入,有没有办法保持进动。

long double x1, x2;
x1= 0.087912088; // Note: 360/4095 = 0.087912088
x2 = 360/4095;
printf("%Lf, %Lf \n",x1, x2);

结果:

x1 =0.087912
x2= 0.000000
4

2 回答 2

10

问题是整数截断..你正在划分两个整数=>结果将是另一个整数,小数部分被丢弃。(例如,在整数除法的实际结果为 3.9 的情况下,截断将使其变为 3(即它不四舍五入))。

在您的情况下,如果您将其更改为:

x2 = 360 / 4095.0;  /* one of the operands now has a decimal point */

你会得到

0.087912, 0.087912 

作为输出。

即,只要除法运算符的一个或两个/操作数都是浮点数/双精度数,结果也会是浮点数/双精度数(即,它将被“提升”为浮点数/双精度数)。所以我本可以x2改为

x2 = 360.0 / 4095.0;

或者

x2 = 360.0 / 4095;

并且会得到与上面相同的结果。

正如@chris 所提到的,只使用 a.也足够了。

关于您上面关于精度的问题:

您已经在使用长双打了.. 我不认为在内部您可以更改任何内容,除非您使用一些特殊的库,但您当然可以显示更多数字。例如,

  printf("%Lf, %.20Lf \n",x1, x2); 

将产生

  0.087912, 0.08791208791208791895 

最后,正如@edA-qa mort-ora-y 提醒我们的那样,您还可以值强制转换为某些类型,但是您这样做时很重要。一个简单的例子(请注意,在任何情况下,值都会在赋值float 之后v结束,因为是 a float):

float v = 0;
                     /* values shown are BEFORE assignment */
v = (5 / 2);         /* value is 2 due to integer truncation before assignment */
v = (float) (5 / 2); /* 2.0 as integer division occurs 1st, then cast to float */
v = (float) 5 / 2;   /* 2.5 since 5 becomes 5.0 through casting first. */
于 2012-06-16T02:22:26.967 回答
3

内置运算符适用于相同类型的对象。结果与参数的类型相同。在这种情况下,除法是对两个整数进行的,因此结果是一个整数。

x2 = 360/4096;
//   int/int  = int

因此,我期望结果为 0。

如果内置类型上的运算符不同,则将提升它们以使它们具有相同的类型(并且结果也是该类型)。所以你想要的是:

x2 = 1.0 * 360/4095;  // or 360.0/4095

// This is
    double * int / int

==> (double * double)/int
==> (double * double)/double
于 2012-06-16T02:28:13.230 回答