【问题标题】:GCC default integer/floating arithmetic behaviorGCC 默认整数/浮点算术行为
【发布时间】:2018-12-10 14:33:11
【问题描述】:

我有一组非常长的方程式,我最初针对 MATLAB 编写了这些方程式。现在,我必须将它移植到我的控制器的嵌入式 C 中。

当写double a = 1/3; 时,C 和 C++ 的默认行为是返回 0,因为它被解析为整数算术。我想知道是否有办法关闭这种行为,这样我就不需要将 .0 附加到方程中的每个常数。

比如下面是比较短的一个:

eq = (121.0/16.0*pow(d,4)*pow(r,2)*pow(x,10)+2*pow(r,2)*pow(11.0/6.0,3)*pow(d,4)*pow(x,10) + pow(r,2)*pow(11.0/6.0,6)*pow(d,6)*pow(x,18) + pow(r,2)*pow(d,2)*pow(x,2) - pow(jmax,2));

我的目标是一台 ARM 计算机,所以我使用的是 Linaro GCC。

编辑:

事实证明,改变 GCC 行为是一个巨大的禁忌。 感谢@Matteo Italia,使用正则表达式解决了这个问题。 最终编写了一个基于 Qt 的小型解决方案,用于将 ^ 替换为电源符号并将尾随 .0 添加到文字数字,可在此处获得: https://github.com/pauloasherring/MATEquationToC 如果您要使用它,请自行承担风险:)

【问题讨论】:

  • pow(d,4) 中,4 将通过函数调用转换为double,但在诸如1/3 之类的表达式中,您需要更改其中至少一个的类型double 的操作数。例如:1./31/3.(double)1/31/(double)3 都将计算为 0.333333....
  • 哪个 ARM?如果它是较小的 Cortex M 之一,那么您可以告诉 MATLAP 迷路,因为它们没有 FPU。
  • @Lundin,它是 Cortex A-8,采用 Beaglebone Black。
  • 您可以添加 F 或 D 而不是 .0 并追踪所有常量,而不仅仅是没有任何小数点的常量...如果/当您必须这样做时(很确定您必须下面指出)。
  • @user2162550 M0 到 M3 没有 FPU。在 M4 上是可选的。

标签: c gcc floating-point


【解决方案1】:

没有。这是基本语法,不能更改。

即使有可能,我也会不惜一切代价避免它,因为您的 C 项目将不再是实际的 C,而是一些奇怪的方言,在数字文字的语义上存在 巨大 差异;重用您项目中的代码、从另一个项目中导入代码或让其他人在您的项目上工作都会造成正确性风险。

FWIW,可以通过简单的正则表达式添加缺失的点,例如:

搜索:([^.]|^)\b([0-9]+)\b([^.]|$)

替换:$1$2.0$3

(为了最大的可移植性,无需后视/前瞻)

【讨论】:

  • 我明白了。我昨天尝试了一些正则表达式,设法用pow(name1,N) 替换了简单的表达式,例如name1^N,但是当求幂需要更长的参数时,例如(name1/name2*xyz)^N,它会失败。至于替换数字,我无法这样做。使用regexr.com 尝试了您的解决方案,但它似乎也不起作用。 :(
  • 如果您选择 PCRE 引擎而不是 JS 引擎,它确实可以工作,尽管可以通过使用 $ 而不是 \ 替换变量来轻松修复它。
  • 好的!对于前几个,它按预期工作!我将测试翻译更大更复杂的方程!谢谢!
  • 在某些情况下我不得不运行它两次。我想这取决于引擎,但是,使用 regexr.com 网站,在第一次运行时它会在第一次运行 (121/ 时找到样本 eq = (121/16);,产生 (121.0/,在第二次运行时,在复制结果文本到示例文本区域,它将找到/16),最后用/16.0) 替换它。这种行为可能是因为两个字符串中出现重叠。
  • @PauloSherring:是的,那是因为我作弊了,而且我没有使用前瞻/后瞻...可以修复,现在我知道您使用的是什么引擎。您可以使用([^.]|^)\b([0-9]+)\b(?![.]) 作为搜索和$1$2.0 作为替换。
【解决方案2】:

尝试使用种姓:double a = (double) 1/3..

【讨论】:

  • 我认为这更糟。 OP 希望避免必须在整个代码中的每个常量上附加 .0,添加显式转换会更加耗时并且代码会变得混乱。
  • @JorgeJuanTorresQuiroga:仍然,它很好地解决了 OP 的问题——强制编译器使用浮点数而不是整数。在预处理源时,这将与当前解决方案一样有效,为所有嫌疑人添加一个句点。
猜你喜欢
  • 2017-02-01
  • 1970-01-01
  • 2019-07-25
  • 1970-01-01
  • 1970-01-01
  • 2018-08-19
  • 2012-12-23
  • 1970-01-01
  • 2013-06-12
相关资源
最近更新 更多