【问题标题】:Rounding floating numbers in C [closed]在C中舍入浮点数[关闭]
【发布时间】:2017-07-18 12:42:44
【问题描述】:

我需要对一些存储为浮点数的数字进行四舍五入。

值类似于:0.000000123,例如表示 123ns

我需要提取 123(以便可以用 ns 表示)并将其四舍五入到下一个“十”。

所以,例如我想提取:130e-9

你有什么建议吗?

【问题讨论】:

  • 您知道 0.000000123 不是精确的浮点值(在 IEEE754 下)?
  • 我不明白你的意思......
  • 所以 123 轮到 130 是你在说什么?所以当你谈论十位时,2不是十位,所以你已经乘以1000000000然后你想四舍五入到最接近的十位?
  • 关于displaying scientific notation in C的另一个讨论
  • 您正在使用以 10 为底的数字并询问浮点计算机(以 2 为底)的问题。许多以 10 为底的数字不能用浮点数精确表示,这就是 Bathsheba 所说的

标签: c floating-point rounding


【解决方案1】:

有几种方法可以做rounding,但听起来你正在寻找四舍五入(向+i​​nfinity四舍五入),也称为ceil

由于您有秒单位并且想要获得 10ns 单位,您需要除以 10ns(1e-8,与乘以 1e8 相同),然后使用 ceil 函数。比如

double val = 123e-9;
int val10ns = ceil(val*1e8);

(这假设您有 c99 ceil 可用,如果没有看到 here 的实现)

那么如果你想把它输出为一个字符串,你只需要转换'val10ns'并附加“0ns”,像这样

printf("val in units of 10ns: %d0ns\n", val10ns);

最后,您可能想要做一些事情来处理小值。例如,1e-90 秒仍将舍入到 10ns。例如,您可以先对零进行四舍五入以获得 ns 的单位,然后再进行 ceil 以获得 10ns 的单位。

【讨论】:

  • 这对 OP 来说是一个很好的答案——(除了int val10ns。我用过double val10ns)我没有看到DV 的原因。
  • 我同意 - 舍入结果的双精度也可以,特别是因为双精度可以表示 int 的所有可能值而不会丢失信息。
【解决方案2】:

如果可以忽略注释中出现的对浮点数的担忧,则想法是将给定数字乘以大于一。然后乘以 100 得到该点之后的其他数字,然后继续进行。

 double a; // is given a non-zero for example 0.0000000123...
 double num = a;
 while(num < 1.)
 {
      num *= 10;
 } // at the end of the while 1.23...
 num *= 10; //12.3...
 int result = ((int)num)*10 + 10; // 130

result 是您想要的。它的单位取决于上下文。

但是,它在计算级别上有一些错误。如您所知,计算是以 2 为基数进行的,所有这些以 10 为基数的计算都可能在以 2 为基数的一些计算错误。要找到这个,您可以关注this issue。 因此,您可以仅在算法视图中查看此代码。

【讨论】:

  • 这为123e-7123e-9123e-12 提供相同的result
  • 是的,正如我所说,这取决于时间单位。
  • 另外,可以从迭代次数中找到单位,但问题中没有询问。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-05-23
  • 2015-09-07
  • 1970-01-01
  • 2011-06-09
  • 1970-01-01
  • 2022-12-07
  • 1970-01-01
相关资源
最近更新 更多