【问题标题】:Calculating pow with doubles gives wrong results用双打计算 pow 会给出错误的结果
【发布时间】:2014-11-23 13:31:13
【问题描述】:

我正在 Arduino 上编写计算器,我正在尝试计算 pow 并将其写入字符串(结果)。这是我的代码:

dtostrf(exp(n*log(x)), 0, 5, result); // x ^ n

2 ^ 2 = 4.00000 // works fine

10 ^ 5 = 99999.9770 // should be 100000

我的代码有什么问题,我怎样才能始终得到正确的结果? 我的意思是如何舍入它但仍然可以使用双打(例如 5.2 ^ 3.123)

【问题讨论】:

  • 查看this question的答案。
  • Arduino Uno 有一个非常简单的处理器,没有任何浮点支持。结果是 double 根本不是双精度的,它需要 4 个字节并且在软件中以单精度模拟。精度的损失当然是不可避免的,你永远不能指望超过 6 个精确数字。为此类问题寻找解决方案是 Arduino 爱好者忙碌的原因。
  • 好的,这意味着我可以使用浮点数而不是双精度数?
  • 不,float 也是 4 个字节。在到期时,double 将比float 提供更高的精度;在 Uno 上,它们将是相同的。 float 永远不会比double更多的精度。

标签: c++ c arduino double pow


【解决方案1】:

您只是遇到了舍入错误。对此您无能为力,除非输入为整数时恢复为基于整数的方法。

您可以判断输入是否为整数,如果是,则使用整数算术;如果没有,则使用双打。但是使用explog 总是会引入舍入错误,所以你不能期望用这种方法得到确切的答案。

更准确地说,要使用整数运算,您需要底数是整数,指数是非负整数。

【讨论】:

  • 好的,但是计算器如何在使用双打时得到正确的结果?
  • @AkimWright 我怀疑当输入是整数时他们也会使用整数算术。
  • 好的,我的代码现在检查 floor(x) == x && floor(n) == n 。效果很好
【解决方案2】:

由于您正在编写计算器,因此您关心的不是速度,而是可靠数字的数量。因此,您可以尝试使用双精度库。它使用 64 位双精度,但在 16MHz CPU 时钟下只有大约 200 FLOPS,而在 exp()、log() 或 sin() 等高阶计算中则更少。因此,在输入数字并按下回车键后需要一秒钟,但旧的基于 8 位的袖珍计算器也是如此。

看到这个Link (only in German)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多