【问题标题】:Division and floating points除法和浮点数
【发布时间】:2012-06-16 02:21:00
【问题描述】:

谁能帮我解释为什么 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

【问题讨论】:

  • 克里斯和列文感谢您的回复。有没有办法增加岁差。
  • 要实际存储更多数字,您需要一个任意精度的库。正如 Levon 所说,或者在 C++ 中使用std::setprecision,可以只显示更多内容。
  • @chris 我正在研究 QNX 嵌入式系统上的低级电机控制代码是 C。对于 c++ 代码,我会牢记这一点。
  • 为了让其他人在未来不那么混淆,请考虑以下两个字典条目:precessionprecision
  • 感谢@Alex 指出这一点。

标签: c floating-point floating-accuracy


【解决方案1】:

问题是整数截断 .. 你正在划分两个整数 => 结果将是另一个整数,小数部分被丢弃。 (例如,在整数除法的实际结果为 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 所述,仅使用. 也足够了。

关于精度的问题是:

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

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

将产生

  0.087912, 0.08791208791208791895 

最后,正如@edA-qa mort-ora-y 提醒我们的那样,您还可以 值转换为某些类型,但重要的是何时 这样做。一个简单的例子(请注意,在任何情况下,由于vfloat,因此赋值后的值在任何情况下都会以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. */

【讨论】:

  • 最后一个点也可以。
  • @chris 谢谢 .. 我没有意识到 .. 学到了一些新东西 :) 我会把这个添加到答案中。
  • 您也可以转换为浮点数,如果您需要提升变量而不是常量,这将很有帮助。 float(a) , double(4)
  • @edA-qamort-ora-y 好点,感谢您的提醒,我会在答案中添加有关投射的说明。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-08
    • 2011-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多