【问题标题】:Why do my floats insist on staying integers?为什么我的花车坚持保持整数?
【发布时间】:2012-02-24 22:04:06
【问题描述】:

我正在阅读几个整数,它们代表年、儒略日、小时和分钟。我正在尝试将它们转换为小数天数。

int YYYY, JJJ, HH, MM;

float datenumber = (YYYY*360.0f)+(JJJ*1.0f)+((HH*1.0f)+(MM/60.0f))/24.0f;

使用2001, 083, 22, 32 的值,我应该得到724043.939 的结果。相反,我得到724044

我将所有整数转换为浮点数。为什么它们保持为整数?

edit 是的,我用 cout 显示输出。 setprecision 解决了这个问题,谢谢。

【问题讨论】:

  • 你如何查看最终值;调试器,printf() ?
  • 如何打印结果?问题可能出在您的打印语句中
  • 根据my testprintf显示了预期的结果,但cout显示了“错误”的值。
  • 请注意,尽管使用浮点数进行算术运算存在危险,但它们并不精确。
  • 我正在尝试转换为序列号,就像在 Matlab 的 datenum 函数中一样,所以我可以轻松地比较时间序列,并填写缺失的分钟和秒。有一个更好的方法吗?双精度比浮点数更精确吗?

标签: c++ floating-point


【解决方案1】:

问题不在于您的数字或您的计算。它只是以您显示它的方式。 cout 已决定 6 位数对您来说就足够了。如果需要更多信息,请使用 setprecision

std::cout << std::setprecision(10) << datenumber;

demo

【讨论】:

  • 不,这里发生了一些更可疑的事情。看看这个:codepad.org/TfRlPfOh
  • @Jacob,您会得到该输出,因为作为float,变量的值真的是 432000。它没有足够的精度来保存其余部分价值。见my exact-float page
  • 不是cout 决定 6 个就足够了;它是 C++ 标准。六是任何新 basic_ios 后代的默认精度。
【解决方案2】:

你需要做两件事

  1. 将精度设置为最大值 (cout.setprecision(16))
  2. 转换为doubledouble dateNumberYYYY*360.0

【讨论】:

  • my test 就是这样做的。肯定不止这些。
  • @RobKennedy:我认为将其更改为 double 并更改精度应该可以解决它。
【解决方案3】:

除非您有更多代码在其他地方进行强制转换,否则您在完成等式后进行强制转换,因此您会得到一个浮点数,但在您的强制转换下降之前使用等式中的整数小数。

为什么不最初将它们声明为浮点数?

float YYYY, JJJ, HH, MM;

【讨论】:

  • 他使用float 常量作为*/ 的其他操作数,因此在这些操作完成之前ints 被提升为floats。这意味着你提到的不是问题。编辑:Dan F 下面所说的是正确的。
  • 如果涉及浮点数,它不总是做浮点运算吗?因此int*float 不会被截断,除非你强制转换...
  • 啊,是的,应该知道...我的错
【解决方案4】:

以下可能是原因- 1.可能是你打印错了。 2.除以整数,用float代替。

示例-不是除以 200 除以 200.0

【讨论】:

    【解决方案5】:

    从您在本杰明的回答中提供的示例中的输入和输出值来看,我敢打赌问题只是浮点精度。仅仅因为您将某些东西声明为浮点数,并不意味着它可以处理任何大小的数字。问题在于您的年份组件(1200*360=432000)比您的 MM 组件(5/60/24=.00347222)大得多。 MM 部分的小数部分被忽略,因为浮点数不是那么准确。尝试将 .000001 添加到 123456789 作为浮点数,看看你的输出是什么

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-06
      • 2016-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-26
      • 1970-01-01
      相关资源
      最近更新 更多