【问题标题】:Are values rounded when only printed?仅打印时值是否四舍五入?
【发布时间】:2013-07-02 09:31:12
【问题描述】:

抱歉这个问题不好,但我认为某些变量的舍入有问题。

在我的 C 应用程序中,我必须计算消耗的能量和传感器节点的剩余能量。这是每 10 秒计算一次,如下所示:

cycle_energy = (some long mathematical computation)

energy_spent += cycle_energy;
remaining_energy -= cycle_energy;

在应用程序开始时,这两个量被初始化为:

static float energy_spent = 0;
static float remaining_energy = 1000000;

然后每 10 秒打印一次这两个值。由于我使用的 gcc 支持浮点数进行计算但不支持​​打印,因此我将这两个量转换为 unsigned long。

printf("Energy spent: %lu \n", (uint32_t) energy_spent);
printf("Remaining energy: %lu \n", (uint32_t) remaining_energy);

问题是,在应用程序结束时,数量 1000000 - energy_spent 应该等于 remaining_energy 的计算方式。

但是,这在我的应用程序中并非如此。 1000000 - energy_spentremaining_energy 的数量一开始非常相似,但随着时间的推移它们的差异会增加。

例如,在应用程序结束时,在一个情况下是energy_spent = 207223remaining_energy = 792093,在另一个情况下是energy_spent = 215695remaining_energy = 783828

我认为唯一的问题在于打印值时,但是我认为仅打印值时它们没有四舍五入。

提前致谢。

【问题讨论】:

  • .f 后缀为float 例如static float remaining_energy = 1000000.f;
  • @DavidRF 他为什么要这么做?
  • @DavidRF 你的意思是我的变量remaining_energy被初始化为整数吗?
  • @rasen %f 不适用于 msp430 gcc,因为我需要将它们转换为无符号整数。
  • 您可以使用 printf 的 %f 标志打印浮点数。当您打印转换为 uint32_t 的值时,该值不是四舍五入而是截断。

标签: c floating-point printf


【解决方案1】:

您只是在体验浮动漂移 - 这绝对不是不寻常的!

规范的方法是

static float energy_spent = 0;
static float total_energy = 1000000;
remaining_energy = 1000000;

然后

energy_spent += cycle_energy;
remaining_energy = total_energy - energy_spent;

【讨论】:

  • 浮漂是什么原因?我在网上什么也没找到。谢谢。
  • @aliants,原因是 float 没有有效位来存储值,并且存在一些计算错误。经过多次计算,这些错误得到了总结。
  • 如果您将舍入误差同化为具有某种分布的白噪声,例如,对于基本运算,在 [-ulp/2,ulp/2] 中均匀分布,那么您对 ​​+= 噪声所做的操作正在累积那些导致你积分的错误是白噪声,一种布朗噪声。 += 和 -= 这两个操作的噪声大多是独立的,因此漂移(你可以预测漂移的方差,它可能像时间的平方根一样增加)
【解决方案2】:

您的问题在于浮点类型本身。它没有足够的有效位来按原样存储您的值。

查看此主题:Number of significant digits for a floating point type

【讨论】:

  • 非常感谢。这意味着,对于等于 1000000 的浮点变量,我在存储高达 0.0001% 时可能会出错,这意味着每个周期最多为 1。这就是浮漂的原因吧?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-22
  • 1970-01-01
  • 2011-08-30
  • 2014-07-26
  • 2023-01-12
相关资源
最近更新 更多